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