Windows Phone7 Mango版本的浏览器与IE 9桌面版几乎相同,这意味着WP7+能够渲染HTML5内容并运行HTML5应用。尽管与Chrome相比,它支持的HTML5元素较少,但一些重要特性如地理位置和画布功能表现良好。如果希望在离线模式下打开HTML应用,可能会遇到一些问题。目前,WP 7 Mango的WebBrowserControl无法像Android和iOS等竞争对手那样,导航到手机文件系统中的HTML文件。这意味着只能开发传统的HTML5 Widget应用。通过WPWidgetLibrary,可以将HTML 5 Widget应用构建为原生的WP7应用。之后,可以在Windows Phone Marketplace上发布它,并轻松更新应用。该库的工作原理是在首次安装时,通过模拟真实硬盘的方式,将HTML5内容安装到隔离存储中,以及HTML页面、脚本、图像等的路径。在这个项目中受到了Windows Mobile 6.5 Widget Apps的启发。
WPWidgetLibrary包含一个类,实现了HTML5应用离线运行的全部逻辑。以下代码展示了WPWidgetLibrary类的架构:
public class WidgetLibrary
{
private List<string> m_Subfolders = new List<string>();
public void InstalHTMLContent(string htmlFolder, string[] htmlDirs);
private bool iswebResource(string webResource);
protected virtual bool isWebExtension(string ext);
private string getFileNameFromResourceName(string assemblyReplacement, string webResource);
private void copyFile(IsolatedStorageFile isoFile, string webResourceFileName, Stream webResourceStream);
private void resolveSubfolders(string[] directories);
private string createRequiredDirectory(IsolatedStorageFile isolatedStorageFile, string webResourceFileName);
private void deleteDirectory(IsolatedStorageFile isolatedStorageFile, string root);
private bool IsFirstTimeRun();
}
这个类的主要思想是公共方法InstalHTMLContent(string htmlFolder, string[] htmlDirs)。让看看该方法的实现:
public void InstalHTMLContent(string htmlFolder, string[] htmlDirs)
{
if (htmlDirs == null)
throw new Exception("No html folder structure passed!");
if (!IsFirstTimeRun())
return;
Debug.WriteLine("Application runs for the first time!");
resolveSubfolders(htmlDirs);
var asm = Assembly.GetCallingAssembly();
using (IsolatedStorageFile isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
{
deleteDirectory(isolatedStorageFile, String.Empty);
foreach (var webResource in asm.GetManifestResourceNames())
{
if (iswebResource(webResource))
{
var pos = webResource.ToLower().IndexOf(htmlFolder.ToLower());
if (pos > 0)
copyFile(isolatedStorageFile, getFileNameFromResourceName(webResource.Substring(0, pos + htmlFolder.Length + 1), webResource), asm.GetManifestResourceStream(webResource));
else
throw new InvalidOperationException("invalid resource name.");
}
}
}
}
HTML内容必须作为嵌入式资源包含在项目中。上述方法根据输入参数htmlDirs将资源内容提取到隔离存储中。在提取过程中,文件和文件夹结构必须与原始结构相同,以确保链接和路径有效。
注意,此方法仅在应用程序首次运行时调用,这对于使用HTML5应用时的本地数据存储和持久对象非常重要。
通过使用WPWidgetLibrary,只需几个步骤就可以制作出功能完备的混合Windows Phone7应用程序。该库仅在Windows Phone 7.1上运行,因此必须安装Windows Phone 7.1 Developer Tool for Visual Studio 2010。
在WP7.1项目中引用WPWidgetLibrary DLL。将HTML(应用)复制到某个项目文件夹中,并将所有文件在构建操作中标记为EmbeddedResource。从工具箱中拖动WebBrowser控件,并在PageLoaded事件中导航到所需的网页。(参见XAML文件中的红色矩形。)
在MainPage构造函数中,添加以下代码。此代码将在应用程序启动时,将所有HTML相关内容复制到隔离存储。InstallHTMLContent的字符串数组(第二个参数)应包含项目的所有子文件夹,这些子文件夹也需要复制到隔离存储中。如果应用非常简单,所有文件都在一个文件夹中,那么这个参数就不需要了。
var wdgt = new WPWidgetLibrary();
wdgt.InstalHTMLContent(
"HTML",
new string[] {
"js/jQueryMobile/images",
"SubContent/SubSubContent",
});
在MainPage Loaded事件中,将初始页面设置为WebBrowser控件。以下代码是常见的WebBrowser代码,它开始浏览页面。请注意,导航页面(StartPage.htm)不是托管在线的页面。它是隔离存储中的页面。
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
// Navigate to initial page of the HTML app
webBrowser1.Navigate(new Uri("StartPage.htm", UriKind.Relative));
}
编译并运行应用程序,将看到一个功能完备的HTML Widget应用程序。
默认情况下,WPWidgetLibrary仅支持有限数量的文件格式,这些格式可以成为HTML5应用的一部分。例如,如果想将AVI文件添加到HTML5应用中,需要创建一个派生自基类的实现类。以下代码显示了支持AVI文件格式的示例。
public class MyWPWidgetLibrary : WPWidgetLibrary{
protected override bool IsWebExtension(string ext){
bool res = false;
switch (ext.ToLower())
{
case "avi":
return true;
break;
}
return base.IsWebExtension(ext);
}
}