崔麗梅+薛斐斐
摘要:PhoneGap技術(shù)使得開發(fā)者可以使用符合W3C標(biāo)準(zhǔn)的Web技術(shù)開發(fā)本地應(yīng)用。通過調(diào)用PhoneGap的API,Web應(yīng)用程序就可以與開發(fā)者所使用的移動平臺 SDK API 進(jìn)行交互,并進(jìn)行該平臺的本地功能調(diào)用。PhoneGap提供的插件開發(fā)與引入方式,可以讓開發(fā)者針對自己的特殊需要引入新的插件或者開發(fā)自己的插件。經(jīng)過測試對比發(fā)現(xiàn),使用PhoneGap技術(shù)比使用WebView技術(shù)開發(fā)的移動應(yīng)用具有更好的性能。
關(guān)鍵詞: PhoneGap;JavaScript;跨平臺;Android;移動應(yīng)用
中圖分類號:TP311 文獻(xiàn)標(biāo)識碼: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技術(shù)簡介
PhoneGap是一個開源框架,目前由美國Adobe公司進(jìn)行開發(fā)和維護(hù)。使用PhoneGap可以將使用HTML、CSS、JavaScrip以及HTML5+CSS3編寫的Web APP構(gòu)建為跨平臺的移動應(yīng)用程序。其主要前景在于:通過作為Javascript和本地代碼之間的橋梁的PhoneGap,不僅能夠?qū)eb應(yīng)用項(xiàng)目方便的打包為本地應(yīng)用,更可以通過PhoneGap的插件調(diào)用Android設(shè)備的其他本地特性,例如攝像頭、地理信息、本地網(wǎng)絡(luò)設(shè)置等,并且開發(fā)者可以根據(jù)具體的硬件需要和業(yè)務(wù)要求開發(fā)針對自己設(shè)備的PhoneGap插件。
2 PhoneGap技術(shù)原理與實(shí)現(xiàn)流程
2.1 PhoneGap跨平臺原理
利用PhoneGap技術(shù),開發(fā)人員通過使用 CSS 和 HTML 來設(shè)計程序 UI 并控制程序的邏輯;同時,使用 JavaScript 來調(diào)用 API 與對應(yīng)平臺的 SDK 進(jìn)行交互,以啟動手機(jī)的 GPS、震動、重力感應(yīng)等功能。使用 PhoneGap 編寫的程序會被打包并安裝到手機(jī)上,在應(yīng)用運(yùn)行時載入到手機(jī)的瀏覽器控件中解析執(zhí)行[4]。
PhoneGap框架為開發(fā)者提供了一系列的 API,這些API可以在 JavaScript 代碼中調(diào)用;在實(shí)際的開發(fā)過程中,通過這些API調(diào)用,PhoneGap程序就可以與開發(fā)者所使用的移動平臺 SDK API 進(jìn)行交互,并進(jìn)行該平臺本地功能的實(shí)際調(diào)用工作。開發(fā)完畢后,用戶使用該應(yīng)用時,開發(fā)者使用Web技術(shù)編寫的html、css以及JavaScript文件就會以“鏡像文件”的形式被打包并發(fā)布到用戶所在的移動平臺中。實(shí)際運(yùn)行時,由該平臺所內(nèi)嵌的Web瀏覽器進(jìn)行解析并執(zhí)行,這樣就實(shí)現(xiàn)了一次開發(fā),跨多平臺運(yùn)行的功能。PhoneGap 目前支持幾乎所有的移動應(yīng)用平臺,如iOS、Android、Windows Phone、黑莓和WebOS等。
2.2 PhoneGap通過JavaScript調(diào)用Java流程
本文所探討的PhoneGap技術(shù)將以Android平臺為例,并基于PhoneGap 1.6、Android 2.3.6版本進(jìn)行探討和測試。下面通過簡單的HelloWorld程序說明在Android平臺中基于PhoneGap開發(fā)的應(yīng)用程序的運(yùn)行原理。
以下JavaScript代碼段實(shí)現(xiàn)了通過PhoneGap調(diào)用Android設(shè)備上的震動通知功能,當(dāng)程序運(yùn)行,用戶點(diǎn)擊主程序中的"震動2秒"按鈕,設(shè)備將持續(xù)震動2秒。而這個功能的實(shí)現(xiàn),僅需要像編寫Web應(yīng)用一樣,在html頁面上加入以下幾行JavaScript代碼。并引入phonegap.js和phonegap.jar兩個類庫的支持。
考慮用戶點(diǎn)擊主程序上的"震動2秒"按鈕后,此JavaScript代碼是如何調(diào)用Android API的。當(dāng)用戶點(diǎn)擊按鈕后,在phonegap.js中的Notification.prototype.vibrate方法就會接收到該調(diào)用,接著調(diào)用PhoneGap.exec方法。如下代碼段所示:
Notification.prototype.vibrate = function(mills) {
PhoneGap.exec(null, null, "Notification", "vibrate", [mills]);
};
PhoneGap.exec方法被調(diào)用后,它會調(diào)用prompt ( JSON. stringify(args), "gap:"+JSON. stringify ([service, action, callbackId, true]))方法以完成JavaScript與Java的通信。此時,Android系統(tǒng)的WebView組件就會企圖彈出一個窗口。使用Android提供的 WebChromeClient API 就可以截獲 WebView 的這個動作 。具體到PhoneGap 1.6 就是繼承了WebChromeClient 的com.phonegap.CordovaChromeClient 類中的onJsPrompt方法。
在onJsPrompt方法中執(zhí)行pluginManager.exec(service, action, callbackId, message, async)方法。此時,PlugManager 會根據(jù)收到參數(shù),將命令分發(fā)給特定的Plugin,也就是插件。關(guān)于PhoneGap的插件,將在下一節(jié)詳細(xì)介紹。在本例中,接收的plugin是Notification;接收到的action是vibrate;參數(shù)為2000毫秒。由此,PhoneGap調(diào)用Notification 中的 this.vibrate(args.getLong(0))方法,通知設(shè)備震動2000毫秒。
Notification類中的vibrate方法沒有返回值,但是在其他PhoneGap插件中,常見有success和error兩種基本返回值,以JSON對象的形式返回,以便于通知用戶,程序執(zhí)行的狀態(tài)。而此返回值都可以在主程序頁面上捕獲并輸出。因此總結(jié)PhoneGap中的JavaScript調(diào)用Java流程,可如圖1所示。
2.3 PhoneGap通過Java調(diào)用JavaScript流程
PhoneGap實(shí)現(xiàn)了一個回調(diào)服務(wù)器,服務(wù)器就是負(fù)責(zé)回調(diào)JavaScript代碼的,服務(wù)器有一個JavaScript代碼的隊列,在src/com/phonegap/CallbackServer.java文件中:
/**
* The list of JavaScript statements to be sent to JavaScript.
*/
private LinkedList javascript;
服務(wù)器保存要回調(diào)的JavaScript的代碼,供JavaScript客戶端取回,這里Java端是服務(wù)器端,JavaScript端是客戶端,服務(wù)器端不可能請求客戶端,所以PhoneGap實(shí)現(xiàn)了兩種服務(wù)模型,一種是輪詢,一種是XHR異步回調(diào),也就是Ajax的模型。在PhoneGap源碼目錄中,src/com/phonegap/ CallbackServer.java文件即是回調(diào)服務(wù)器的代碼。
CallbackServer提供的上述兩種模型,輪詢方式的原理較為簡單,在使用時,callbackserver服務(wù)器端將會保存一個回調(diào)JavaScript的列表,每隔一段時間客戶端的JavaScript會詢問一次服務(wù)器,是否有需要回調(diào)的JavaScript,如果有則進(jìn)行具體的調(diào)用。而基于XHR的方式也就是Ajax用的機(jī)制,JavaScript發(fā)起一個異步請求,服務(wù)器會在返回數(shù)據(jù)之前保持住這個連接,當(dāng)返回數(shù)據(jù)就位后,服務(wù)器給請求客戶端返回數(shù)據(jù),然后關(guān)閉連接??蛻舳私邮盏椒祷財?shù)據(jù)后進(jìn)行處理。客戶端JavaScript的相關(guān)代碼如下:
PhoneGap.JSCallback = function() {
...
xmlhttp.open("GET", "http://127.0.0.1:"+PhoneGap.JSCallbackPort+"/"+PhoneGap.JSCallbackToken , true);
xmlhttp.send();
}
這個是XHR模型的代碼,客戶端JavaScript使用XHR請求服務(wù)器來獲取JavaScript代碼,進(jìn)行回調(diào)。
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段時間,就請求一次服務(wù)器(通過prompt("", "gap_poll:");)[8]。
3 基于Android平臺的簡單PhoneGap應(yīng)用開發(fā)
3.1 開發(fā)流程
1)啟動Eclipse,然后在菜單“File”下選擇“New > Android Project”。在項(xiàng)目根目錄下,創(chuàng)建兩個新目錄: /libs
/assets/www
2)復(fù)制phonegap.js(從PhoneGap解壓縮后的Android目錄中,將解壓縮后的帶版本號的js文件名修改為phonegap.js)到/assets/www。
復(fù)制phonegap.jar(從PhoneGap解壓縮后的Android目錄中)到/libs。右鍵單擊/libs文件夾找到Build Paths/ > Configure Build Paths。然后在Libraries標(biāo)簽頁中添加phonegap.jar到項(xiàng)目中。復(fù)制xml整個目錄(從PhoneGap解壓縮后的Android目錄中,包括一個plugins.xml)到/res。
3) 對Eclipse的src文件夾中的主要Java文件進(jìn)行少量調(diào)整:
將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。將下面的權(quán)限設(shè)置拷貝到versionName之后: (在實(shí)際開發(fā)中,要根據(jù)需要開放程序權(quán)限)
5)在 “/assets/www”目錄中新建文件“index.html”,并粘貼如下代碼:
3.2 部署與運(yùn)行
1)右鍵單擊項(xiàng)目節(jié)點(diǎn)選擇Run As,然后點(diǎn)擊Android Application。
2)Eclipse將要求你選擇一個合適的AVD(Android虛擬機(jī)),如果沒有設(shè)置的話,你需要創(chuàng)建一個AVD或者將一個實(shí)際的Android設(shè)備連接到電腦。
3)確認(rèn)設(shè)備已經(jīng)勾選USB debugging選項(xiàng),并已將設(shè)備連接到電腦。(設(shè)置 > 應(yīng)用程序 > 開發(fā))
4)右鍵單擊項(xiàng)目節(jié)點(diǎn)選擇Run As,點(diǎn)擊Android Application,稍等片刻便可以在AVD或?qū)嶋H的Android設(shè)備中看到運(yùn)行效果。
4 PhoneGap插件與WebView方式性能對比測試
4.1測試目的
在使用PhoneGap之前,大多數(shù)將Web應(yīng)用轉(zhuǎn)移到基于Android平臺的本地應(yīng)用都是使用Android系統(tǒng)自帶的WebView方式,通過對比由WebView原生支持的Java與JavaScript通信方式和由PhoneGap插件支持的通信方式的差別,可以為開發(fā)者提供借鑒,并為使用PhoneGap技術(shù)提供理論依據(jù)。眾所周知,在移動平臺中,系統(tǒng)資源是非常緊張的,如何在給定系統(tǒng)資源下擴(kuò)大程序性能以及效率是所有移動應(yīng)用程序都必須關(guān)注的問題,本次測試同樣著重對比使用不同技術(shù)時資源耗費(fèi)、性能、效率問題。
4.2 測試環(huán)境
硬件環(huán)境:
設(shè)備型號:Motorola ME525+ 智能手機(jī);處理器:德州儀器 OMAP3620 1GHz;內(nèi)存容量:512MB RAM + 2GB ROM;屏幕參數(shù):TFT彩色屏幕;480×854像素(FWVGA),3.7英寸。
軟件環(huán)境:
設(shè)備操作系統(tǒng):Android OS v2.3.3;
開發(fā)環(huán)境:Eclipse SDK Version: 3.6.0;java version 1.6.0_17; PhoneGap 1.6。
測試工具:使用Android SDK自帶的測試工具M(jìn)onkey,Monkey是Android SDK中的一個命令行工具,可以運(yùn)行在模擬器里或?qū)嶋H設(shè)備中。它向系統(tǒng)發(fā)送偽隨機(jī)的用戶事件流(如按鍵輸入、觸摸屏輸入、手勢輸入等),實(shí)現(xiàn)對正在開發(fā)的應(yīng)用程序進(jìn)行壓力測試。Monkey測試是一種為了測試軟件的穩(wěn)定性、健壯性的快速有效的方法[7]。
4.3測試用例
為了保證測試的準(zhǔn)確性,使用WebView方式和PhoneGap插件方式分別開發(fā)了兩個簡單的調(diào)整系統(tǒng)聲音大小并顯示的小應(yīng)用。
使用WebView方式,以HTML+JavaScript開發(fā)的頁面事件調(diào)用Android系統(tǒng)功能使用的是Android系統(tǒng)組件WebView的addJavascriptInterface方法,該方法捕獲html頁面事件并調(diào)用對應(yīng)的Android原生方法,將最終結(jié)果以調(diào)用JavaScript的方式返回。
使用PhoneGap的方式,需要引入PhoneGap所依賴的類庫,然后進(jìn)行開發(fā)。PhoneGap在應(yīng)用運(yùn)行時會加載所需的插件,而后根據(jù)頁面事件的不同調(diào)用相應(yīng)的Android原生方法。調(diào)用的方式為通過對頁面prompt事件的捕獲,傳遞請求參數(shù)和返回參數(shù)。與直接使用WebView的方式不同的是,利用PhoneGap可以通過已經(jīng)被封裝好的方法進(jìn)行Java與JavaScript的通信,代碼邏輯清晰,易于開發(fā)和修改。
4.4測試結(jié)果
使用Monkey對測試用例進(jìn)行10000次事件的注入,觀察其性能與響應(yīng)如表1所示:
通過表1的測試結(jié)果可以看出,使用PhoneGap的插件方式進(jìn)行的Java與JavaScript相互調(diào)用進(jìn)行10000次所需時間208465ms,占用內(nèi)存9.0MB,相對于WebView方式的180802ms和7.3MB內(nèi)存占用,其效率顯然要稍低一些。然而,考慮到PhoneGap在初始化時就加載了自己所有的核心插件,因此有必要精簡這一部分進(jìn)行對比測試。
4.5 改進(jìn)后的測試結(jié)果
PhoneGap在應(yīng)用被系統(tǒng)加載時,自動初始化加載了所有核心插件,但這些插件大部分對于我們的程序是無用的。刪掉與本測試用例無關(guān)的諸多PhoneGap核心插件,例如GPS、網(wǎng)絡(luò)、羅盤等,理論上可以減小PhoneGap初始化所占用的系統(tǒng)資源。經(jīng)過刪除其插件加載后進(jìn)行再次測試,可以發(fā)現(xiàn),對改進(jìn)后的PhoneGap測試用例進(jìn)行10000次的隨機(jī)事件注入耗時198214ms,測試完畢后占用內(nèi)存5.3MB。雖然耗時仍大于基于WebView的測試用例,但是消耗內(nèi)存明顯降低。由此可看出,基于PhoneGap的測試用例經(jīng)過優(yōu)化精簡后,效率大幅度提升。
5 PhoneGap技術(shù)小結(jié)
PhoneGap的優(yōu)勢是顯而易見的,跨平臺、易于使用、特別是對于目前正在使用JavaScript與HTML5+CSS3技術(shù)的開發(fā)者來說,可以將現(xiàn)有Web App快速的移植到各種流行的移動應(yīng)用平臺上。更重要的是,通過PhoneGap的插件模式,可以將復(fù)雜業(yè)務(wù)交由本地代碼執(zhí)行,不但提高效率,更增強(qiáng)了代碼的可靠度。
PhoneGap將幫助程序開發(fā)團(tuán)隊借助Web應(yīng)用項(xiàng)目開發(fā)經(jīng)驗(yàn)進(jìn)入跨平臺的移動本地應(yīng)用開發(fā)領(lǐng)域。在掌握HTML,CSS以及JavaScript技術(shù)后,在使用PhoneGap不會遇到任何問題。所需的只是對其API組件進(jìn)行明確介紹的文檔。另外,如果需要讓應(yīng)用和遠(yuǎn)程Web服務(wù)進(jìn)行通信,通過PhoneGap可以方便的引入JQuery的支持,以便創(chuàng)建強(qiáng)大的Ajax操作。隨著PhoneGap自身的發(fā)展,更多的移動平臺將被統(tǒng)一納入其支持框架中,這無論對于應(yīng)用開發(fā)者還是移動平臺提供商都有著巨大的市場前景。
參考文獻(xiàn):
[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] 關(guān)于跨平臺移動應(yīng)用開發(fā)框架的探索[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開發(fā)二:開發(fā)一個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源碼解析——插件機(jī)制,java和js代碼互調(diào)用詳解[EB/OL].http://www.qhm123.com/ 2012/01/28/phonegap-source-code-analyzing-java-js-plugin-mechanism.html
[8] 袁琦. 跨平臺嵌入式開發(fā)環(huán)境研究[J].電腦與電信,2008(11).
[9] 李春虎. 基于Qt的跨平臺軟件設(shè)計及應(yīng)用[D].電子科技大學(xué),2011.
[10] 趙勝海. 設(shè)計模式在嵌入式軟件設(shè)計中的研究與應(yīng)用[D].四川大學(xué),2006.
[11] 鐘文. 網(wǎng)絡(luò)時代高校校友網(wǎng)絡(luò)管理系統(tǒng)[D].華南理工大學(xué),2012.
[12] 牟杰. Director軟件促進(jìn)了跨平臺開發(fā)[J].多媒體世界,1995(11).
[13] 何畏. 物化探軟件跨平臺移植技術(shù)的探討[J].物探化探計算技術(shù),2011(6).
[14] 鐘文. 網(wǎng)絡(luò)時代高校校友網(wǎng)絡(luò)管理系統(tǒng)[D].華南理工大學(xué),2012.
[15] 李寶韓. 基于Android的PhoneGap平臺研究及其跨移動平臺媒體框架的擴(kuò)展[D].華南理工大學(xué),2012.
[16] 楊安祺. 視窗操作系統(tǒng)下的視窗化編程方法研究[J].西北輕工業(yè)學(xué)院學(xué)報,2001(4).
[17] 張馳. 基于C++語言的跨平臺軟件開發(fā)的設(shè)計與實(shí)現(xiàn)[D].北京交通大學(xué),2010.