借助Apache Cordova構建混合移動應用程序
譯文【51CTO譯文】你已完成了為應用程序構建前端的工作,它還有了移動支持功能?,F在你想提供用戶們可以從應用程序商店下載的原生客戶端應用程序。讀完該教程后,你會明白如何重復使用現有的HTML5代碼,借助Apache Cordova,針對每個目標平臺開發原生的移動客戶端程序。
你將學會如何:
•對現有的Web應用程序進行改動,好讓應用程序可以作為一個混合移動應用程序來部署。
•借助Apache Cordova,開發面向安卓和iOS的原生應用程序。
什么是混合移動應用程序?
混合移動應用程序是用HTML5開發的――不像原生應用程序編譯成針對特定平臺的二進制代碼。客戶端代碼完全由HTML、CSS和JavaScript組成,包裝起來后安裝在客戶端設備上,完全像任何原生應用程序那樣,然后在周圍的原生外殼生成的瀏覽器進程里面執行。
除了封裝瀏覽器進程外,原生外殼還允許訪問原生設備功能,比如方向感應器、GPS、聯系人名單等,應用程序則可以通過JavaScript庫來使用這些功能。
在該例子中,我們使用Apache Cordova部署混合應用程序,該應用程序使用了TicketMonster的現有HTML5移動前端,并與在JBoss A7或JBoss企業應用平臺(EAP)上運行的TicketMonster部署環境的充分利用代表性狀態傳輸協議(REST)的服務進行交互。
圖1:混合TicketMonster的架構
改動應用程序以便遠程訪問
在我們讓應用程序成為混合應用程序之前,需要對應用程序訪問遠程服務的方式做一些改變。請注意:這些變化已經實現在用戶前端,我們在此為你顯示了需要改動的代碼。
在Web版本的應用程序中,客戶端代碼與服務器端代碼一起部署,那樣模型和集合(還有將執行REST服務調用的任何部分代碼)可以使用相對應用程序根目錄的URL:所有資源都由同一臺服務器來提供,所以瀏覽器將進行正確的調用。這還尊重瀏覽器在默認情況下執行的同源策略,以防止跨站腳本攻擊。
如果客戶端代碼與服務分開來部署,REST調用必須使用絕對URL(我們會在后面探討給同源策略帶來的影響)。此外,由于我們希望不必重新構建源代碼,就能夠將該應用程序部署到不同的主機上,所以它必須是可以配置的。
你已經在用戶前端章節大體了解了這方面,我們在那個章節為移動版應用程序定義了configuration(配置)模塊。
- src/main/webapp/resources/js/configurations/mobile.js
- ...
- define("configuration", function() {
- if (window.TicketMonster != undefined && TicketMonster.config != undefined) {
- return {
- baseUrl: TicketMonster.config.baseRESTUrl
- };
- } else {
- return {
- baseUrl: ""
- };
- }
- });
- ...
該模塊有一個baseURL屬性,既可以設置代表相對URL的空字符串,也可以設置成前綴,比如域名,這取決于名為TicketMonster的全局變量是否早已被定義,它擁有baseRESTUrl屬性。
我們所有執行REST服務調用的代碼都依賴該模塊,因而基本REST URL可以在單單一個地方加以配置,并注入到整段代碼中,正如下列代碼實例所示:
- src/main/webapp/resources/js/app/models/event.js
- /**
- * 事件模型的模塊
- */
- define([
- 'configuration',
- 'backbone'
- ], function (config) {
- /**
- * 事件模塊類定義
- * 用于對單個事件執行CRUD(創建讀取更新刪除)操作
- */
- var Event = Backbone.Model.extend({
- urlRoot: config.baseUrl + 'rest/events' // the URL for performing CRUD operations
- });
- // 輸出事件類
- return Event;
- });
執行REST服務調用的其他所有模塊以相似的方式使用前綴。眼下你沒必要做任何事情,因為我們在用戶前端教程中編寫的代碼最初就是這樣編寫而成的。不過小心,如果你有一個移動Web應用程序使用任何相對URL,就需要對它們進行重構,以便加入某種URL配置。
#p#
安裝混合移動工具和CordovaSim
混合移動工具(Hybrid Mobile Tools)和CordovaSim還沒有作為JBoss Developer Studio的一部分而安裝。它們可以從JBoss Central來安裝,如下所示:
1. 想安裝這些插件,只需把下面這個鏈接拖到JBoss Central: https://devstudio.jboss.com/central/install?connectors=org.jboss.tools.aerogear.hybrid。另外在JBoss Central中,選擇Software/Update(軟件/更新)選項卡。在Find(查找)欄,鍵入JBoss Hybrid Mobile Tools,或者滾動瀏覽列表,找到JBoss Hybrid Mobile Tools + CordovaSim。選擇相應的復選框,并點擊Install(安裝)。
圖2:通過鏈接,開始混合移動工具和CordovaSim的安裝過程。
圖3:在JBoss Central的軟件/更新選項卡中找到混合移動工具和CordovaSim。
在安裝向導中,確保已為你想要安裝的軟件選擇了復選框,并點擊Next(下一步)。建議你安裝所有已選擇的組件。
仔細查看列出來安裝的項目的細節,并點擊Next(下一步)。在閱讀并同意許可證后,點擊I accept the terms of the license agreement(s),即我接受許可證協議的條款,點擊Finish(完成)。Installing Software(安裝軟件)窗口就會打開,報告安裝進度。
在安裝過程中,你可能會收到警告,提醒要安裝未簽名內容。如果真是這樣,仔細閱讀內容細節,如果對內容滿意,就點擊OK(確定),繼續安裝。
圖4:提示安裝的軟件含有未簽名內容的警告。
一旦安裝完成,會提示你重啟IDE。點擊Yes(確定),即可立即重啟;如果你需要保存對所打開項目改動的任何未保存內容,就點擊No(不)。注意:IDE重啟后,改動才生效。
一旦安裝完畢,你必須將安卓SDK的位置告知混合移動工具,之后才能使用涉及安卓的混合移動工具動作。
想設定安卓SDK的位置,點擊Window(窗口)→ Preferences(偏好設置),選擇Hybrid Mobile(混合移動)。在Android SDK Directory(安卓SDK目錄)欄,鍵入已安裝SDK的路徑,或者點擊Browse(瀏覽),瀏覽到相應位置。點擊Apply(應用),并點擊OK(確定),即可關閉Preferences(偏好設置)窗口。
圖5:偏好設置窗口的混合移動面板
#p#
開發混合移動項目
1. 想開發一個新的混合移動項目,點擊File(文件)→ New(新建)→ Other(其他),選擇“Hybrid Mobile (Cordova) Application Project”,即“混合移動(Cordova)應用程序項目”。
圖6:開始開發一個新的混合移動應用程序項目
2. 輸入項目信息:應用程序名稱、項目名稱和程序包。
項目名稱
TicketMonster-Cordova
名稱
TicketMonster-Cordova
ID
org.jboss.jdf.example.ticketmonster.cordova
圖7:開發一個新的混合移動應用程序項目
點擊Next(下一步),為該項目選擇混合移動引擎。如果你之前在JBoss Developer Studio中從未安裝過混合移動引擎,就會提示你下載或搜索可以使用的引擎。我們將點擊Download(下載)按鈕來執行前一項操作。
圖8:頭一次安裝混合移動引擎
系統會提示一個對話框,你可以下載所有可用的混合移動引擎。
圖9:選擇要下載的混合移動引擎
我們將選擇版本3.4.0的安卓和iOS變種。
圖10:為3.4.0選擇安卓和iOS
我們已經下載并安裝了混合移動引擎,現在不妨將它用在我們的項目中。選擇剛配置好的引擎,并點擊Finish(完成)。
圖11:開發一個新的混合移動應用程序項目
一旦你完成了開發項目的任務,瀏覽到www目錄,該目錄里面含有應用程序的HTML5代碼。由于我們重復使用TicketMonster代碼,你只要把www目錄換成TicketMonster的webapp目錄的符號鏈接;config.xml文件和rest目錄需要拷貝過去,拷貝到TicketMonster的webapp目錄。另外,你可以拷貝TicketMonster的代碼,并在那里作所有必要的改動(不過在那種情況下,你在兩個地方都需要維護應用程序的代碼。)
- $ cp config.xml $TICKET_MONSTER_HOME/demo/src/main/webapp
- $ cp res $TICKET_MONSTER_HOME/demo/src/main/webapp
- $ cd ..
- $ rm -rf www
- $ ln -s $TICKET_MONSTER_HOME/demo/src/main/webapp www
圖12:將www與webapp目錄鏈接起來的結果
混合移動工具要求cordova.js文件裝入到應用程序的起始頁面。由于我們不想把該文件裝入到現有的index.html文件中,就要創建一個只由Cordova應用程序才可以使用的新的起始頁面。
- src/main/webapp/mobileapp.html
- <!DOCTYPE html>
- <html>
- <head>
- <title>Ticket Monster</title>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
- <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"/>
- <script type="text/javascript" src="resources/js/libs/modernizr-2.6.2.min.js"></script>
- <script type="text/javascript" src="resources/js/libs/require.js"
- data-main="resources/js/configurations/loader"></script>
- </head>
- <body>
- </body>
- </html>
現在不妨修改混合移動項目的配置,使用該頁面作為應用程序的起始頁面。此外,我們將把我們的REST服務URL添加到config.xml文件中的域白名單(為了簡單起見,你在開發過程中還可以使用“*”):
- src/main/webapp/config.xml
- <?xml version="1.0" encoding="utf-8"?>
- <widget xmlns="http://www.w3.org/ns/widgets" xmlns:gap="http://phonegap.com/ns/1.0"
- id="org.jboss.jdf.example.ticketmonster.cordova" version="2.0.0">
- ...
- <!-- The application start page -->
- <content src="mobileapp.html" />
- <!--
- Add the TicketMonster cloud app to the domain whitelist.
- Domains are assumed blocked unless set otherwise.
- -->
- <access origin="http://ticketmonster-jdf.rhcloud.com"/>
- ...
- </widget>
下一步,我們需要將庫裝入到應用程序。我們還將構建一個單獨的模塊。除了裝入面向安卓的Apache Cordova JavaScript庫外,該模塊還將裝入移動應用程序的其余部分。我們還需要配置應用程序的基本URL。就這個例子而言,我們將使用部署在云端的TicketMonster的URL。
- src/main/webapp/resources/js/configurations/hybrid.js
- // 為充分利用REST的服務覆蓋配置
- var TicketMonster = {
- config:{
- baseRESTUrl:"http://ticketmonster-jdf.rhcloud.com/"
- }
- };
- require(['../../../cordova'], function() {
- var bootstrap = {
- initialize: function() {
- document.addEventListener('deviceready', this.onDeviceReady, false);
- },
- onDeviceReady: function() {
- // 檢查是不是iOS 7或更高版本,禁止覆蓋狀態欄
- if(window.device.platform.toLowerCase() == "ios" &&
- parseFloat(window.device.version) >= 7.0) {
- StatusBar.overlaysWebView(false);
- StatusBar.styleDefault();
- StatusBar.backgroundColorByHexString("#e9e9e9");
- }
- // 裝入移動模塊
- require (["mobile"]);
- }
- };
- bootstrap.initialize();
- });
注意:我們將使用OpenShift主機托管版的TicketMonster應用程序,因為它在所有環境下訪問起來更容易――智能手機模擬器和仿真器也能訪問它,基本上不需要什么配置。另一方面,訪問本地運行的JBoss EAP實例可能需要一番復雜的網絡配置;要是需要向互聯網打開實例,以便可以從智能手機訪問,更是錯綜復雜。
上述代碼片段含有面向iOS 7的針對特定設備的檢查機制。我們將使用Cordova狀態欄插件,確保iOS 7上的狀態欄并不重疊用戶界面。Cordova設備插件將用來獲得檢測設備時所用的設備信息。我們還將使用Cordova通知插件,向使用原生移動用戶界面的最終用戶顯示提醒和通知。
我們將繼續把所需的Cordova插件添加到項目。
選擇混合移動項目的plugins目錄,通過右擊鼠標打開上下文菜單。選擇菜單中的Install Cordova Plug-in(安裝Cordova插件)選項。這會打開一個對話框,你可以在上面搜索各個位置下的Cordova插件,包括Cordova注冊中心、git軟件庫或你文件系統中的目錄。
圖13:啟動Cordova插件發現向導
現在我們將搜索并添加所需的插件:
圖14:添加Cordova設備插件
圖15:添加Cordova通知插件
圖16:添加Cordova狀態欄插件
點擊Next(下一步)按鈕,核實所要安裝的插件版本。點擊Finish(完成)按鈕,即可下載插件,并安裝到項目。
圖17:核實所要添加的插件
最后一步需要調整src/main/webapp/resources/js/configurations/loader.js,以便在安卓上運行時裝入該模塊,使用我們已經在項目中配置的查詢字符串。我們還將調整src/main/webapp/resources/js/app/utilities.js,以便使用通知插件,在混合移動應用程序的上下文中顯示提醒。
- src/main/webapp/resources/js/configurations/loader.js
- //檢測要裝入的合適模塊
- define(function () {
- /*
- 針對客戶端的簡單檢查。如果是觸摸設備或低分辨率屏幕,
- 顯示移動客戶端。通過啟用低分辨率屏幕上的移動客戶端,
- 我們允許在移動設備外面進行測試(比如JBoss Tools和
- JBoss Developer Studio中的移動瀏覽器模擬器)。
- */
- var environment;
- if (document.URL.indexOf("mobileapp.html") > -1) {
- environment = "hybrid";
- }
- else if (Modernizr.touch || Modernizr.mq("only all and (max-width: 768px)")) {
- environment = "mobile";
- } else {
- environment = "desktop";
- }
- require([environment]);
- });
現在我們將仔細檢查utilities對象中的displayAlert函數。它被設置成一旦有通知插件,就使用該插件:
- src/main/webapp/resources/js/app/utilities.js
- ...
- // 顯示模板的utility函數
- var utilities = {
- ...
- applyTemplate:function (target, template, data) {
- return target.empty().append(this.renderTemplate(template, data));
- },
- displayAlert: function(msg) {
- if(navigator.notification) {
- navigator.notification.alert(msg);
- } else {
- alert(msg);
- }
- }
- };
- ...
由于這類環境中缺少navigator.notification對象,該函數自動適用于非移動環境。
#p#
運行混合移動應用程序
現在你可以準備運行應用程序了。混合移動應用程序可以在使用混合移動工具的設備和模擬器上運行。
在安卓設備或模擬器上運行
注意:
你需要為安卓做什么?
想在安卓設備或模擬器上運行,你就要安裝安卓開發者工具,這需要Eclipse實例(可以使用JBoss Developer Studio),可以在Windows(XP、Vista和7)、Mac OS X(10.5.8或更新版本)、Linux(GNU C Library - glibc 2.7或更新版本,已安裝運行32位應用程序所需庫的64位發行版)上運行。
你必須在自己的系統上安裝安卓API 17或更新版本,那樣才能使用Run on Android Emulator(在安卓模擬器上運行)這個動作。
想在設備上運行該項目,在Project Explorer(項目資源管理器)視圖中,鼠標右擊項目名稱,點擊Run As(運行方式)→Run on Android Device(在安卓設備上運行)。這個選項調用外部安卓SDK來包裝工作區項目,如果一個安卓設備已連接上,就在安卓設備上運行。要注意:必須安裝安卓SDK,另外必須正確配置IDE以便使用安卓SDK,那樣這個選項才會成功執行。
想在模擬器上運行項目,在Project Explorer(項目資源管理器)視圖中,鼠標右擊項目名稱,點擊Run As(運行方式)→Run on Android Emulator(在安卓模擬器上運行)。
圖18:在安卓模擬器上運行應用程序
這要求你構建安卓AVD(安卓虛擬設備),以便在虛擬設備中運行應用程序。
一旦部署完畢,應用程序現在可以在模擬器中用來交互。
圖19:在安卓AVD上運行的應用程序
在iOS模擬器上運行
注意:
你需要為iOS做什么?
使用OS X操作系統時,這個選項才會顯示,OS X有iOS模擬器。你必須安裝Xcode 4.5+,它包括iOS 6 SDK。你還要安裝面向iOS 5.x或更高版本的模擬器,以便在模擬器上運行項目。你可能需要更高版本的模擬器才能運行應用程序,這取決于你可能使用的各種Cordova插件。
在Project Explorer(項目資源管理器)視圖中,鼠標右擊項目名稱,點擊Run As(運行方式)→Run on iOS Emulator(在iOS模擬器上運行)。
圖20:在iOS模擬器上運行應用程序
該選項調用外部iOS SDK,將工作區項目包裝成XCode項目,然后在iOS模擬器上運行。
圖21:在iOS模擬器上運行的應用程序
在CordovaSim上運行
CordovaSim讓你可以在本地工作區中運行混合移動應用程序。你可以開發應用程序,不需要部署到實際設備上,甚至不需要部署到仿真器和模擬器上,就能實現應用程序的行為。你在使用CordovaSim能實現什么功能方面有一些限制;比如說,有些Cordova插件可能與CordovaSim無法兼容。但總的來說,你得到的是更快的開發周期。
在Project Explorer(項目資源管理器)視圖中,鼠標右擊項目名稱,點擊Run As(運行方式)→Run with CordovaSim(與CordovaSim一起運行)。這會在CordovaSim中打開應用程序,它由BrowserSim模擬設備和設備輸入面板組成。
圖22:在CordovaSim上運行的應用程序
結束語
這篇教程介紹了借助Apache Cordova構建混合應用程序的全過程。你可能看到了我們如何將一個可正常運行的HTML5 Web應用程序改成可以直接在安卓和iOS上運行的應用程序。
英文原文:Creating hybrid mobile versions of the application with Apache Cordova
布加迪編譯,轉載請注明譯者及譯文原文出處。











































