基于PhoneGap技术的跨平台移动应用开发探讨
2016-07-04崔丽梅薛斐斐
崔丽梅+薛斐斐
摘要:PhoneGap技术使得开发者可以使用符合W3C标准的Web技术开发本地应用。通过调用PhoneGap的API,Web应用程序就可以与开发者所使用的移动平台 SDK API 进行交互,并进行该平台的本地功能调用。PhoneGap提供的插件开发与引入方式,可以让开发者针对自己的特殊需要引入新的插件或者开发自己的插件。经过测试对比发现,使用PhoneGap技术比使用WebView技术开发的移动应用具有更好的性能。
关键词: PhoneGap;JavaScript;跨平台;Android;移动应用
中图分类号:TP311 文献标识码:A 文章编号:1009-3044(2016)15-0030-04
Abstract:With PhoneGap method, developers can use Web technical which correspond to the W3C standard developing native mobile application. According to call the API of PhoneGap, Web applications can communicate with the SDK API of the mobile platform which using by the developers, and then, they can use the native functions of the mobile platform. PhoneGap provides a method to develop plugins and import plugins, this method makes developers develop their own plugins or import new plugins to meet their special demands. According to the contrast testing, the mobile applications using PhoneGap method have a better performance than the applications using WebView method.
Key words:PhoneGap; JavaScript; Cross-platform; Android; Mobile Application
1 PhoneGap技术简介
PhoneGap是一个开源框架,目前由美国Adobe公司进行开发和维护。使用PhoneGap可以将使用HTML、CSS、JavaScrip以及HTML5+CSS3编写的Web APP构建为跨平台的移动应用程序。其主要前景在于:通过作为Javascript和本地代码之间的桥梁的PhoneGap,不仅能够将Web应用项目方便的打包为本地应用,更可以通过PhoneGap的插件调用Android设备的其他本地特性,例如摄像头、地理信息、本地网络设置等,并且开发者可以根据具体的硬件需要和业务要求开发针对自己设备的PhoneGap插件。
2 PhoneGap技术原理与实现流程
2.1 PhoneGap跨平台原理
利用PhoneGap技术,开发人员通过使用 CSS 和 HTML 来设计程序 UI 并控制程序的逻辑;同时,使用 JavaScript 来调用 API 与对应平台的 SDK 进行交互,以启动手机的 GPS、震动、重力感应等功能。使用 PhoneGap 编写的程序会被打包并安装到手机上,在应用运行时载入到手机的浏览器控件中解析执行[4]。
PhoneGap框架为开发者提供了一系列的 API,这些API可以在 JavaScript 代码中调用;在实际的开发过程中,通过这些API调用,PhoneGap程序就可以与开发者所使用的移动平台 SDK API 进行交互,并进行该平台本地功能的实际调用工作。开发完毕后,用户使用该应用时,开发者使用Web技术编写的html、css以及JavaScript文件就会以“镜像文件”的形式被打包并发布到用户所在的移动平台中。实际运行时,由该平台所内嵌的Web浏览器进行解析并执行,这样就实现了一次开发,跨多平台运行的功能。PhoneGap 目前支持几乎所有的移动应用平台,如iOS、Android、Windows Phone、黑莓和WebOS等。
2.2 PhoneGap通过JavaScript调用Java流程
本文所探讨的PhoneGap技术将以Android平台为例,并基于PhoneGap 1.6、Android 2.3.6版本进行探讨和测试。下面通过简单的HelloWorld程序说明在Android平台中基于PhoneGap开发的应用程序的运行原理。
以下JavaScript代码段实现了通过PhoneGap调用Android设备上的震动通知功能,当程序运行,用户点击主程序中的"震动2秒"按钮,设备将持续震动2秒。而这个功能的实现,仅需要像编写Web应用一样,在html页面上加入以下几行JavaScript代码。并引入phonegap.js和phonegap.jar两个类库的支持。
//震动2秒
function vibrate() {
navigator.notification.vibrate(2000);
}
考虑用户点击主程序上的"震动2秒"按钮后,此JavaScript代码是如何调用Android API的。当用户点击按钮后,在phonegap.js中的Notification.prototype.vibrate方法就会接收到该调用,接着调用PhoneGap.exec方法。如下代码段所示:
Notification.prototype.vibrate = function(mills) {
PhoneGap.exec(null, null, "Notification", "vibrate", [mills]);
};
PhoneGap.exec方法被调用后,它会调用prompt ( JSON. stringify(args), "gap:"+JSON. stringify ([service, action, callbackId, true]))方法以完成JavaScript与Java的通信。此时,Android系统的WebView组件就会企图弹出一个窗口。使用Android提供的 WebChromeClient API 就可以截获 WebView 的这个动作 。具体到PhoneGap 1.6 就是继承了WebChromeClient 的com.phonegap.CordovaChromeClient 类中的onJsPrompt方法。
在onJsPrompt方法中执行pluginManager.exec(service, action, callbackId, message, async)方法。此时,PlugManager 会根据收到参数,将命令分发给特定的Plugin,也就是插件。关于PhoneGap的插件,将在下一节详细介绍。在本例中,接收的plugin是Notification;接收到的action是vibrate;参数为2000毫秒。由此,PhoneGap调用Notification 中的 this.vibrate(args.getLong(0))方法,通知设备震动2000毫秒。
Notification类中的vibrate方法没有返回值,但是在其他PhoneGap插件中,常见有success和error两种基本返回值,以JSON对象的形式返回,以便于通知用户,程序执行的状态。而此返回值都可以在主程序页面上捕获并输出。因此总结PhoneGap中的JavaScript调用Java流程,可如图1所示。
2.3 PhoneGap通过Java调用JavaScript流程
PhoneGap实现了一个回调服务器,服务器就是负责回调JavaScript代码的,服务器有一个JavaScript代码的队列,在src/com/phonegap/CallbackServer.java文件中:
/**
* The list of JavaScript statements to be sent to JavaScript.
*/
private LinkedList javascript;
服务器保存要回调的JavaScript的代码,供JavaScript客户端取回,这里Java端是服务器端,JavaScript端是客户端,服务器端不可能请求客户端,所以PhoneGap实现了两种服务模型,一种是轮询,一种是XHR异步回调,也就是Ajax的模型。在PhoneGap源码目录中,src/com/phonegap/ CallbackServer.java文件即是回调服务器的代码。
CallbackServer提供的上述两种模型,轮询方式的原理较为简单,在使用时,callbackserver服务器端将会保存一个回调JavaScript的列表,每隔一段时间客户端的JavaScript会询问一次服务器,是否有需要回调的JavaScript,如果有则进行具体的调用。而基于XHR的方式也就是Ajax用的机制,JavaScript发起一个异步请求,服务器会在返回数据之前保持住这个连接,当返回数据就位后,服务器给请求客户端返回数据,然后关闭连接。客户端接收到返回数据后进行处理。客户端JavaScript的相关代码如下:
PhoneGap.JSCallback = function() {
...
xmlhttp.open("GET", "http://127.0.0.1:"+PhoneGap.JSCallbackPort+"/"+PhoneGap.JSCallbackToken , true);
xmlhttp.send();
}
这个是XHR模型的代码,客户端JavaScript使用XHR请求服务器来获取JavaScript代码,进行回调。
PhoneGap.JSCallbackPolling = function() {
...
var msg = prompt("", "gap_poll:");
if (msg) {
setTimeout(function() {
try {
var t = eval(""+msg);
}
catch (e) {
console.log("JSCallbackPolling: Message from Server: " + msg);
console.log("JSCallbackPolling Error: "+e);
}
}, 1);
setTimeout(PhoneGap.JSCallbackPolling, 1);
}
else {
setTimeout(PhoneGap.JSCallbackPolling, PhoneGap.JSCallbackPollingPeriod);
}
}
这个是轮询方式的,可以看到客户端每隔PhoneGap.JSCallbackPollingPeriod段时间,就请求一次服务器(通过prompt("", "gap_poll:");)[8]。
3 基于Android平台的简单PhoneGap应用开发
3.1 开发流程
1)启动Eclipse,然后在菜单“File”下选择“New > Android Project”。在项目根目录下,创建两个新目录: /libs
/assets/www
2)复制phonegap.js(从PhoneGap解压缩后的Android目录中,将解压缩后的带版本号的js文件名修改为phonegap.js)到/assets/www。
复制phonegap.jar(从PhoneGap解压缩后的Android目录中)到/libs。右键单击/libs文件夹找到Build Paths/ > Configure Build Paths。然后在Libraries标签页中添加phonegap.jar到项目中。复制xml整个目录(从PhoneGap解压缩后的Android目录中,包括一个plugins.xml)到/res。
3) 对Eclipse的src文件夹中的主要Java文件进行少量调整:
将class的继承由Activity改为DroidGap
将setContentView()替换为super.loadUrl("file:///android_asset/www/index.html ");
添加import com.phonegap.*;
移除import android.app.Activity;
4)右键单击AndroidManifest.xml并选择Open With > Text Editor。将下面的权限设置拷贝到versionName之后: (在实际开发中,要根据需要开放程序权限)
5)在 “/assets/www”目录中新建文件“index.html”,并粘贴如下代码:
// 震动2秒
function vibrate() {
navigator.notification.vibrate(2000);
}
3.2 部署与运行
1)右键单击项目节点选择Run As,然后点击Android Application。
2)Eclipse将要求你选择一个合适的AVD(Android虚拟机),如果没有设置的话,你需要创建一个AVD或者将一个实际的Android设备连接到电脑。
3)确认设备已经勾选USB debugging选项,并已将设备连接到电脑。(设置 > 应用程序 > 开发)
4)右键单击项目节点选择Run As,点击Android Application,稍等片刻便可以在AVD或实际的Android设备中看到运行效果。
4 PhoneGap插件与WebView方式性能对比测试
4.1测试目的
在使用PhoneGap之前,大多数将Web应用转移到基于Android平台的本地应用都是使用Android系统自带的WebView方式,通过对比由WebView原生支持的Java与JavaScript通信方式和由PhoneGap插件支持的通信方式的差别,可以为开发者提供借鉴,并为使用PhoneGap技术提供理论依据。众所周知,在移动平台中,系统资源是非常紧张的,如何在给定系统资源下扩大程序性能以及效率是所有移动应用程序都必须关注的问题,本次测试同样着重对比使用不同技术时资源耗费、性能、效率问题。
4.2 测试环境
硬件环境:
设备型号:Motorola ME525+ 智能手机;处理器:德州仪器 OMAP3620 1GHz;内存容量:512MB RAM + 2GB ROM;屏幕参数:TFT彩色屏幕;480×854像素(FWVGA),3.7英寸。
软件环境:
设备操作系统:Android OS v2.3.3;
开发环境:Eclipse SDK Version: 3.6.0;java version 1.6.0_17; PhoneGap 1.6。
测试工具:使用Android SDK自带的测试工具Monkey,Monkey是Android SDK中的一个命令行工具,可以运行在模拟器里或实际设备中。它向系统发送伪随机的用户事件流(如按键输入、触摸屏输入、手势输入等),实现对正在开发的应用程序进行压力测试。Monkey测试是一种为了测试软件的稳定性、健壮性的快速有效的方法[7]。
4.3测试用例
为了保证测试的准确性,使用WebView方式和PhoneGap插件方式分别开发了两个简单的调整系统声音大小并显示的小应用。
使用WebView方式,以HTML+JavaScript开发的页面事件调用Android系统功能使用的是Android系统组件WebView的addJavascriptInterface方法,该方法捕获html页面事件并调用对应的Android原生方法,将最终结果以调用JavaScript的方式返回。
使用PhoneGap的方式,需要引入PhoneGap所依赖的类库,然后进行开发。PhoneGap在应用运行时会加载所需的插件,而后根据页面事件的不同调用相应的Android原生方法。调用的方式为通过对页面prompt事件的捕获,传递请求参数和返回参数。与直接使用WebView的方式不同的是,利用PhoneGap可以通过已经被封装好的方法进行Java与JavaScript的通信,代码逻辑清晰,易于开发和修改。
4.4测试结果
使用Monkey对测试用例进行10000次事件的注入,观察其性能与响应如表1所示:
通过表1的测试结果可以看出,使用PhoneGap的插件方式进行的Java与JavaScript相互调用进行10000次所需时间208465ms,占用内存9.0MB,相对于WebView方式的180802ms和7.3MB内存占用,其效率显然要稍低一些。然而,考虑到PhoneGap在初始化时就加载了自己所有的核心插件,因此有必要精简这一部分进行对比测试。
4.5 改进后的测试结果
PhoneGap在应用被系统加载时,自动初始化加载了所有核心插件,但这些插件大部分对于我们的程序是无用的。删掉与本测试用例无关的诸多PhoneGap核心插件,例如GPS、网络、罗盘等,理论上可以减小PhoneGap初始化所占用的系统资源。经过删除其插件加载后进行再次测试,可以发现,对改进后的PhoneGap测试用例进行10000次的随机事件注入耗时198214ms,测试完毕后占用内存5.3MB。虽然耗时仍大于基于WebView的测试用例,但是消耗内存明显降低。由此可看出,基于PhoneGap的测试用例经过优化精简后,效率大幅度提升。
5 PhoneGap技术小结
PhoneGap的优势是显而易见的,跨平台、易于使用、特别是对于目前正在使用JavaScript与HTML5+CSS3技术的开发者来说,可以将现有Web App快速的移植到各种流行的移动应用平台上。更重要的是,通过PhoneGap的插件模式,可以将复杂业务交由本地代码执行,不但提高效率,更增强了代码的可靠度。
PhoneGap将帮助程序开发团队借助Web应用项目开发经验进入跨平台的移动本地应用开发领域。在掌握HTML,CSS以及JavaScript技术后,在使用PhoneGap不会遇到任何问题。所需的只是对其API组件进行明确介绍的文档。另外,如果需要让应用和远程Web服务进行通信,通过PhoneGap可以方便的引入JQuery的支持,以便创建强大的Ajax操作。随着PhoneGap自身的发展,更多的移动平台将被统一纳入其支持框架中,这无论对于应用开发者还是移动平台提供商都有着巨大的市场前景。
参考文献:
[1] Andrew Lunny . PhoneGap Binger's Guide[M]. Birmingham B3 2PB, UK. Published by Packt Publishing Ltd,2011:21-22
[2] Thomas Myer. Wrox Beginning PhoneGap [M]. Indianapolis. John Wiley & Sons, Inc.2011.11.
[3] 关于跨平台移动应用开发框架的探索[EB/OL].PhoneGap http://www.ibm.com/developerworks/ cn/opensource/os-cn-phonegap/
[4] 解析PhoneGap插件如何使用[EB/OL].http://mobile.51cto.com/others-290644.htm
[5] Phone Gap开发二:开发一个Phone Gap插件[EB/OL].http://gteam-yu.iteye.com/blog/1358707
[6] Android自动测试[EB/OL].Monkey http://www.cnblogs.com/yyangblog/archive/2011/03/10/ 1980068.html.
[7] phoengap源码解析——插件机制,java和js代码互调用详解[EB/OL].http://www.qhm123.com/ 2012/01/28/phonegap-source-code-analyzing-java-js-plugin-mechanism.html
[8] 袁琦. 跨平台嵌入式开发环境研究[J].电脑与电信,2008(11).
[9] 李春虎. 基于Qt的跨平台软件设计及应用[D].电子科技大学,2011.
[10] 赵胜海. 设计模式在嵌入式软件设计中的研究与应用[D].四川大学,2006.
[11] 钟文. 网络时代高校校友网络管理系统[D].华南理工大学,2012.
[12] 牟杰. Director软件促进了跨平台开发[J].多媒体世界,1995(11).
[13] 何畏. 物化探软件跨平台移植技术的探讨[J].物探化探计算技术,2011(6).
[14] 钟文. 网络时代高校校友网络管理系统[D].华南理工大学,2012.
[15] 李宝韩. 基于Android的PhoneGap平台研究及其跨移动平台媒体框架的扩展[D].华南理工大学,2012.
[16] 杨安祺. 视窗操作系统下的视窗化编程方法研究[J].西北轻工业学院学报,2001(4).
[17] 张驰. 基于C++语言的跨平台软件开发的设计与实现[D].北京交通大学,2010.