Worklight基于HTML5和JavaScript的跨平臺應用
隨著智能手機和平板電腦的普及,越來越多的互聯網 IT 企業把注意力集中到了移動平臺上。目前市場上主流的移動平臺有 Apple 的 iOS, Google 的 Android, 微軟的 Windows Phone, BlackBerry 以及 Nokia 的 Symbian 等。這些移動平臺的開發環境和編程語言都不盡相同。同時,一個平臺又有多個版本,例如 Android2.3 和 Android3.0 分別支持智能手機和平板電腦。正是由于這些多樣性,使得移動應用的開發存在成本高、周期長和維護困難等問題。
Worklight 是 IBM 收購的一套用于移動應用開發和基礎平臺整合的企業級解決方案。它支持多種移動平臺的本地應用開發,同時也支持基于 HTML5 和 JavaScript 的跨平臺應用。
本文主要介紹 Worklight 的 RuntimeSkin 特性以及如何使用該特性開發針對不同移動終端的跨平臺應用。
開發環境安裝與配置
Worklight 提供的是一整套移動應用的開發環境,涵蓋了從開發到集成,到管理、部署、監控行等軟件開發生命周期的各個方面。它主要由四個部分組成,Worklight Studio、 Worklight Server、Device Runtime 和 Worklight Console:
- Worklight Studio 是基于 Eclipse 的集成開發環境,用戶可以很方便地創建、開發、部署和測試不同平臺的本地應用或者混合型應用。
- Worklight Server 是一個基于 Tomcat 的服務器,用于部署開發好的移動應用程序。同時它還提供適配器 (Adapter) 組件來進行用戶登錄驗證、后臺數據交互、消息推送等企業級應用操作。
- Device Runtime 是 Worklight SDK 中包含一個組件,它主要提供了可以調用移動平臺本地資源的多種接口,開發者可以使用 JavaScript API, 操作系統本地庫和第三方庫來調用這些接口,充分利用了本地應用的優點。
- Worklight Console 可以讓用戶通過瀏覽器來監控、管理當前部署在 Worklight Server 上的應用程序和適配器組件。Worklight Console 同時還負責消息推送管理以及報表分析。
Worklight 開發環境的下載與安裝步驟可以從 developerWorks IBM Worklight 學習資源上獲得。
什么是運行時皮膚(Runtime Skin)
運行時皮膚是指 Worklight 的應用程序可以為已經創建好的手機平臺環境(Worklight Environment)添加多個皮膚,每一個皮膚是平臺環境的一個子集,所有的皮膚作為應用程序的一部分打包在安裝文件中。當應用程序運行時會根據具體 的移動設備動態地決定使用哪一個皮膚。運行時皮膚的應用場景有很多,比如不同的手機尺寸,不同的手機平臺版本,是否支持 HTML5 等等。
下面我們以一個新聞瀏覽的應用程序為例,具體介紹如何應用 Worklight 的 Runtime Skin 特性。
創建 Worklight 工程和應用程序
- 我們創建一個 Worklight 工程。在 Eclipse 中選擇 File->New->Worklight Project, 如圖 1 所示。
圖 1. 創建 Worklight 工程
- 輸入工程名稱 Mobile News。接著我們創建一個 Worklight 應用程序,選擇 File->New->Worklight Application,如圖 2 所示。
圖 2. 創建 Worklight 應用程序
- 在彈出的窗口中選擇***步新建的工程,然后輸入應用程序的名稱 NewsApp,如圖 3 所示。
圖 3. 在工程中創建應用程序
- 創建完工程和應用程序以后,Worklight 會自動生成如下的目錄結構,如圖 4 所示。
圖 4. 應用程序目錄結構
我們看到在 apps 目錄下包含剛剛創建的應用程序 NewsApp,初始情況下每一個應用程序會有一個 common 的運行時環境,它會被不同手機平臺環境(例如 iOS, Android, BlackBerry 等)所共用。在 common 文件夾下有三個文件夾 css, images 和 js,分別存放了程序相關的 css 文件,圖片和 JavaScript 文件。NewsApp.html 是程序自動創建的主 html 文件。
在工程中引入 Dojo Mobile
在這個例子中,我們使用 Dojo Mobile 做為手機界面開發的 JavaScript 框架。Dojo Mobile 是 Dojo JavaScript 的一個 mobile 版本擴展,專門為手機移動開發提供很多豐富的控件和不同的 css 主題。
打開 NewsApp.html,在 head 中引用 dojo.js 文件,這里我們使用 CDN 的方式,如清單 1 所示。讀者也可以從 dojo 的官方網站上下載 dojo toolkit 包,拷貝到工程里,然后在 html 文件中引用 dojo.js。
清單 1. 引用 dojo.js
- <script type="text/javascript"
- data-dojo-config="isDebug: false, async: true, parseOnLoad: true"
- src="http://ajax.googleapis.com/ajax/libs/dojo/1.7.2/dojo/dojo.js">
- </script>
- 在 js/NewsApp.js 的 wlCommonInit() 初始化函數中添加相應的 dojo mobile 模塊,這里我們用到的是 AMD 方式,當 require 方法加載完所需的 dojo mobile 模塊以后,會調用 init 這個初始化函數,函數具體的實現放在運行時皮膚。
清單 2. 用 AMD 方式加載 dojo mobile 模塊
- require([
- "dojo",
- "dojox/mobile/parser",
- "dojox/mobile",
- "dojox/mobile/compat",
- ], function(dojo) {
- dojo.ready(function() {
- init();
- });
- });
定義視圖
這個示例程序一共分為兩個視圖:***個視圖是列表視圖,展示多條新聞的標題。第二個視圖是正文視圖,顯示新聞的正文。兩個視圖的交互方式分為兩種, ***種方式是首頁顯示列表視圖,當用戶點擊某一個新聞標題后,轉到正文視圖。點擊正文視圖左上角的返回按鈕,返回到列表視圖,如圖 5 左側所示。這種方式適合小屏幕的手機。
第二種方式是把列表視圖和正文視圖顯示在同一個頁面中,如圖 5 右側所示。頁面左側是新聞列表視圖,頁面右側是正文視圖。用戶可以在列表視圖中選擇新聞標題,相應的新聞正文就會在右側顯示。這種方式適合在平板電腦這種屏幕較大的移動設備上。
圖 5. 兩種顯示方式
在新建皮膚之前,我們需要把不同皮膚共用的代碼放在 common 環境中。
- 首先在 common 環境下新建一個 data 文件夾來存放兩個視圖的模版,分別命名為 list.html 和 detail.html.
清單 3. 列表視圖代碼 - <h1 id="listHead" data-dojo-type="dojox.mobile.Heading" label="News"></h1>
- <ul id="newsList" data-dojo-type="dojox.mobile.EdgeToEdgeList">
- <li data-dojo-type="dojox.mobile.ListItem" moveTo="detailView"
- label="news 1 title"></li>
- <li data-dojo-type="dojox.mobile.ListItem" moveTo="detailView"
- label="news 2 title"></li>
- </ul>
清單 4. 正文視圖代碼- <h1 id="detailHead" data-dojo-type="dojox.mobile.Heading" label="News title"></h1>
- <div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
- <p>This is news body</p>
- </div>
- 在 common/js 中添加通用的 javscript 方法。
清單 5. loadView 方法- function loadView(id, url) {
- var view = new dojox.mobile.ScrollableView({
- id: id,
- selected: true
- });
- var contentPane = new dojox.mobile.ContentPane({
- href: url
- });
- view.addChild(contentPane);
- return view;
- }
loadView 方法主要工作是把列表視圖(list view)和正文視圖(detail view)分別加載到一個 ScrollableView 當中。接下來我們開始創建兩個不同的皮膚以及皮膚相關的代碼。
創建運行時皮膚
首先我們需要新建一個 Worklight 環境,右鍵 NewsApp 工程選擇 New ->Worklight Environment, 如圖 6 所示。
圖 6. 創建 Worklight 環境
Worklight 提供了多種手機平臺環境,包括:iPhone/iPad, Android, BlackBerry 和 Windows Phone 等。在這里我們選擇 Android phones and tablets,如圖 7 所示。
圖 7. 添加 Android phone and tablet 環境
接下來我們創建兩套運行時皮膚,一套針對 Android 手機,另外一套針對 Android 平板電腦。
右鍵 NewsApp 項目,選擇 New -> Worklight Application Skin, 然后選擇 Skin 對用的手機環境為之前創建的 Android phones and tablets, 輸入 skin 的名字 android.phone, 如圖 8 所示。
圖 8. 添加 Android Phone 皮膚
同樣地,我們創建另外一個皮膚,名稱為 android.tablet. Worklight 會自動地將創建完的皮膚在 application-descriptor.xml 中注冊,如清單 6 所示。這里需要注意一點,當我們刪除某一個 skin 的時候,需要在 application descriptor 中手動刪除該 skin 標簽。
清單 6. application-descriptor.xml 中注冊的 skin 信息
- <android version="1.0">
- <skins>
- <skin name="default">
- <folder name="common"/>
- <folder name="android"/>
- </skin>
- <skin name="android.phone">
- <folder name="common"/>
- <folder name="android"/>
- <folder name="android.phone"/>
- </skin>
- <skin name="android.tablet">
- <folder name="common"/>
- <folder name="android"/>
- <folder name="android.tablet"/>
- </skin>
- </skins>
- </android>
每一個皮膚包含了各自的 css 文件,image 圖片和 javascript 方法。我們需要為兩個皮膚創建不同的初始化函數,把列表視圖和正文視圖按照特定的方式加載到主 html 文件中。
- 在 android.phone 的 js 文件夾下新建一個與 common/js 下同名的 js 文件:NewsApp.js,在這個文件里添加初始化函數。
清單 7. phone 皮膚的初始化函數 - function init() {
- var listView = loadView("listView", "data/list.html");
- dojo.place(listView.domNode, dojo.body());
- var detailView = loadView("detailView", "data/detail.html");
- dojo.place(detailView.domNode, dojo.body());
- }
初始化函數把兩個視圖按順序添加到主頁面中,當程序啟動時,顯示***個頁面,也就是列表視圖。當用戶點擊列表視圖中的某一項,就會轉到正文視圖。
- 同樣地,我們在 android.tablet 的 js 文件夾下也新建一個 NewsApp.js,它的初始化函數如下:
清單 8. tablet 皮膚的初始化函數 - function init() {
- var fixedSplitter = new dojox.mobile.FixedSplitter({
- orientation: "H"
- }, dojo.create("div", null, dojo.body(), 'first'));
- fixedSplitter.startup();
- var listView = loadView("listView", "data/list.html");
- var leftPane = new dojox.mobile.ContentPane({
- id: "leftPane",
- content: listView.domNode
- });
- fixedSplitter.addChild(leftPane);
- var detailView = loadView("detailView", "data/detail.html");
- var rightPane = new dojox.mobile.ContentPane({
- id: "rightPane",
- content: detailView.domNode
- });
- fixedSplitter.addChild(rightPane);
- }
在這個初始化函數中,我們用到了 FixedSplitter 這個 dojo mobile 控件,它可以把 mobile 頁面分為多個區域,每個區域可以加載不同的視圖。這里我們把整個頁面分成左右兩塊 leftPane 和 rightPane,分別加載列表視圖和正文視圖。
當我們完成不同皮膚的初始化函數之后,需要在 skinLoader.js 的 getSkinName 方法中添加根據移動設備屏幕大小動態選擇皮膚的代碼。如圖 9 所示。
圖 9. skinLoader.js
清單 9. getSkinName 方法
- function getSkinName() {
- var skinName = "android.phone";
- var screenHeight = screen.height;
- var screenWidth = screen.width;
- if (screenHeight >= 1000 || screenWidth >= 1000) {
- skinName = "android.tablet";
- }
- return skinName;
- }
這個方法根據屏幕的大小來選擇應用哪一個皮膚。注意 skinName 的值要跟創建的皮膚名稱保持一致。
皮膚應用效果
我們把 NewsApp 工程部署到 Worklight Server 上,然后分別在不同手機尺寸的模擬器上運行。圖 10 所示的是運行在小屏幕手機上的效果。圖 11 所示的是運行在大屏幕平板電腦上的效果。
圖 10. 手機顯示效果
圖 11. 平板電腦顯示效果
結束語
運行時皮膚是 Worklight 的一個重要特性,它可以方便地在同一個應用程序中添加多個皮膚外觀,在程序運行時動態地選擇適合移動終端設備的皮膚。本文從一個具體的實例出發,幫助讀者了解運行時皮膚的具體使用方法。