SCMLife.com

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 3015|回复: 1

[推荐] Worklight 移动应用开发之运行时皮肤

[复制链接]
发表于 2013-2-17 10:43:13 | 显示全部楼层 |阅读模式
本帖最后由 技术狂人 于 2013-2-17 10:50 编辑
7 }3 Q4 v# C% }, _" |/ q1 k7 X# \, l1 v: V/ ?5 J$ ?2 h4 w" v+ |6 I- {
引言0 }5 Z  L5 N- k' j) O
随着智能手机和平板电脑的普及,越来越多的互联网 IT 企业把注意力集中到了移动平台上。目前市场上主流的移动平台有 Apple 的 iOS, Google 的 Android, 微软的 Windows Phone, BlackBerry 以及 Nokia 的 Symbian 等。这些移动平台的开发环境和编程语言都不尽相同。同时,一个平台又有多个版本,例如 Android2.3 和 Android3.0 分别支持智能手机和平板电脑。正是由于这些多样性,使得移动应用的开发存在成本高、周期长和维护困难等问题。
9 {0 L; G1 V# u+ L. K* l1 `Worklight 是 IBM 收购的一套用于移动应用开发和基础平台整合的企业级解决方案。它支持多种移动平台的本地应用开发,同时也支持基于 HTML5 和 JavaScript 的跨平台应用。
4 ?) a: d& J1 p9 v本文主要介绍 Worklight 的 RuntimeSkin 特性以及如何使用该特性开发针对不同移动终端的跨平台应用。$ d( G/ c+ ], `) l


: c. W) k! k/ _2 o) [
& Y, B! e+ H0 F- t  e开发环境安装与配置
# Z2 K  A/ Y0 ?/ JWorklight 提供的是一整套移动应用的开发环境,涵盖了从开发到集成,到管理、部署、监控行等软件开发生命周期的各个方面。它主要由四个部分组成,Worklight Studio、 Worklight Server、Device Runtime 和 Worklight Console:
, [# e! X3 g/ _( J+ N! \1 s) ^
  • Worklight Studio 是基于 Eclipse 的集成开发环境,用户可以很方便地创建、开发、部署和测试不同平台的本地应用或者混合型应用。
  • Worklight Server 是一个基于 Tomcat 的服务器,用于部署开发好的移动应用程序。同时它还提供适配器 (Adapter) 组件来进行用户登录验证、后台数据交互、消息推送等企业级应用操作。
  • Device Runtime 是 Worklight SDK 中包含一个组件,它主要提供了可以调用移动平台本地资源的多种接口,开发者可以使用 JavaScript API, 操作系统本地库和第三方库来调用这些接口,充分利用了本地应用的优点。
  • Worklight Console 可以让用户通过浏览器来监控、管理当前部署在 Worklight Server 上的应用程序和适配器组件。Worklight Console 同时还负责消息推送管理以及报表分析。
    / L+ T# G: M4 E3 F- B, k' K6 M
Worklight 开发环境的下载与安装步骤可以从 developerWorks IBM Worklight 学习资源上获得。7 @4 e, B# C' A9 ]


" o, d% m# v) A) l
* D% a/ F" s5 f什么是运行时皮肤(Runtime Skin)0 [0 t' R9 O6 m9 V
运行时皮肤是指 Worklight 的应用程序可以为已经创建好的手机平台环境(Worklight Environment)添加多个皮肤,每一个皮肤是平台环境的一个子集,所有的皮肤作为应用程序的一部分打包在安装文件中。当应用程序运行时会根据具体的移动设备动态地决定使用哪一个皮肤。运行时皮肤的应用场景有很多,比如不同的手机尺寸,不同的手机平台版本,是否支持 HTML5 等等。# O! e$ K, Q9 W2 j4 N
下面我们以一个新闻浏览的应用程序为例,具体介绍如何应用 Worklight 的 Runtime Skin 特性。7 o9 N0 L  A0 ^7 w9 b, K3 I

0 d! ~( w" y2 Z( o  K( ?

% f. t  W/ U- `2 g: E# D创建 Worklight 工程和应用程序5 l  l7 a/ S5 b! i) F
  • 我们创建一个 Worklight 工程。在 Eclipse 中选择 File->New->Worklight Project, 如图 1 所示。                                                         
    ; Z% S" A9 X6 l7 t0 ?) y* I* V
      }; R0 O* x( @& D8 k2 R图 1. 创建 Worklight 工程6 m' @! U8 G8 _4 k5 e
  • 输入工程名称 Mobile News。接着我们创建一个 Worklight 应用程序,选择 File->New->Worklight Application,如图 2 所示。                                                          7 c& T0 n6 h$ S( Q$ ?6 I
    ' \$ R  @4 [$ A
    图 2. 创建 Worklight 应用程序
    3 m3 r6 h4 Q/ o- v) K
  • 在弹出的窗口中选择第一步新建的工程,然后输入应用程序的名称 NewsApp,如图 3 所示。                                                         
    / L" Q- q# {) t0 z9 s3 [! `: @( t" w9 P, E
    图 3. 在工程中创建应用程序
    : n- p  o1 o9 P7 P8 @
  • 创建完工程和应用程序以后,Worklight 会自动生成如下的目录结构,如图 4 所示。                                                         
    * ~( L( I. @$ L& U6 }: O* i3 G1 C0 C/ w' I4 ]$ X3 L+ y
    图 4. 应用程序目录结构7 g$ X+ X# E; Y2 _
    6 n) F4 |8 t/ o
我们看到在 apps 目录下包含刚刚创建的应用程序 NewsApp,初始情况下每一个应用程序会有一个 common 的运行时环境,它会被不同手机平台环境(例如 iOS, Android, BlackBerry 等)所共用。在 common 文件夹下有三个文件夹 css, images 和 js,分别存放了程序相关的 css 文件,图片和 JavaScript 文件。NewsApp.html 是程序自动创建的主 html 文件。
9 g5 O7 e) P4 q! g$ h  K

% [% \& q) Y1 h3 X
1 F3 Z0 Z7 q6 T* _( d+ |在工程中引入 Dojo Mobile
- z) h( u# L9 y; H* o7 P在这个例子中,我们使用 Dojo Mobile 做为手机界面开发的 JavaScript 框架。Dojo Mobile 是 Dojo JavaScript 的一个 mobile 版本扩展,专门为手机移动开发提供很多丰富的控件和不同的 css 主题。
4 I! ^' x  y% ~& E0 D6 t* S5 ~打开 NewsApp.html,在 head 中引用 dojo.js 文件,这里我们使用 CDN 的方式,如清单 1 所示。读者也可以从 dojo 的官方网站上下载 dojo toolkit 包,拷贝到工程里,然后在 html 文件中引用 dojo.js。3 g0 r7 Z/ O3 V
8 p1 c" V7 O1 |* j6 J
清单 1. 引用 dojo.js
: D  P- A) w4 E+ r
                                  " c$ I6 l4 E) X9 P5 S, c% _0 P
<script type="text/javascript"
2 _+ }4 z3 |0 S% R* d" k/ |    data-dojo-config="isDebug: false, async: true, parseOnLoad: true"' W5 u& Q1 x& i# {2 ]* A
    src="http://ajax.googleapis.com/ajax/libs/dojo/1.7.2/dojo/dojo.js">
" J0 K) A) ]* k6 J2 ?. } </script>

& {6 Q; a$ h, s$ P3 ?; N' N
  • 在 js/NewsApp.js 的 wlCommonInit() 初始化函数中添加相应的 dojo mobile 模块,这里我们用到的是 AMD 方式,当 require 方法加载完所需的 dojo mobile 模块以后,会调用 init 这个初始化函数,函数具体的实现放在运行时皮肤。
    / P1 @& t1 U5 a1 X% A3 N/ L

  l+ c1 p) G, S清单 2. 用 AMD 方式加载 dojo mobile 模块7 A. m$ F! h" A3 n; ~
require([ % a0 O( L% `( g1 G& B) D" M0 {
    "dojo",
# E: ~" U$ i% f) E( L" i"dojox/mobile/parser", ' {8 N, c! W1 r1 C% c$ f; R
    "dojox/mobile", 6 R, B8 b- V$ t+ r. ]# g  U5 Q
    "dojox/mobile/compat", ! c% X6 {0 ]3 D8 x* y
    ], function(dojo) { 9 J9 G5 l5 E/ w* s$ X5 |
        dojo.ready(function() { # T. g0 \0 S# F- ]* r  Y* b0 x
            init(); 5 k  ]( m! F3 ^0 E' H% m" k- x5 z
        }); 1 ?  {5 }. {% d# P3 y9 w7 w( G
});

, @7 e4 K( h) i+ ?( e6 T
. s+ }4 |+ I0 K! v  l4 e, i1 x
/ t- y7 h! Q2 r. K+ \
定义视图
% C/ b. B; q  B) o. f这个示例程序一共分为两个视图:第一个视图是列表视图,展示多条新闻的标题。第二个视图是正文视图,显示新闻的正文。两个视图的交互方式分为两种,第一种方式是首页显示列表视图,当用户点击某一个新闻标题后,转到正文视图。点击正文视图左上角的返回按钮,返回到列表视图,如图 5 左侧所示。这种方式适合小屏幕的手机。
/ X& {2 N! ~' _; A: `. h4 b第二种方式是把列表视图和正文视图显示在同一个页面中,如图 5 右侧所示。页面左侧是新闻列表视图,页面右侧是正文视图。用户可以在列表视图中选择新闻标题,相应的新闻正文就会在右侧显示。这种方式适合在平板电脑这种屏幕较大的移动设备上。
$ q0 h; I# b* P7 P; [9 }6 J6 Y3 w+ s6 q
图 5. 两种显示方式
" \) \# T8 \/ j% z
- b8 p+ t1 D$ Z" B, O- T8 m在新建皮肤之前,我们需要把不同皮肤共用的代码放在 common 环境中。
: S' _# k4 ^2 P# [
  • 首先在 common 环境下新建一个 data 文件夹来存放两个视图的模版,分别命名为 list.html 和 detail.html.                         ! L  B- X* |; [* I, V9 z3 n
    ! `. y5 L5 y% Q4 l5 C
    清单 3. 列表视图代码
  • <h1 id="listHead" data-dojo-type="dojox.mobile.Heading" label="News"></h1>
    * x  L2 {9 c6 F4 W <ul id="newsList" data-dojo-type="dojox.mobile.EdgeToEdgeList">
    4 x& q# a5 M8 y' O; e% C5 r    <li data-dojo-type="dojox.mobile.ListItem" moveTo="detailView"- G0 e3 j5 ^8 k! s
         label="news 1 title"></li>
    , d( P. g- }# T; n1 p: R" P    <li data-dojo-type="dojox.mobile.ListItem" moveTo="detailView" ' N1 g2 u7 y1 H/ A0 y% U" I
        label="news 2 title"></li> 3 c/ c  c( p5 g2 w% d
    </ul>
    ) t+ p* m# D& U2 H/ q" G( x* r
  • 清单 4. 正文视图代码
  • <h1 id="detailHead" data-dojo-type="dojox.mobile.Heading" label="News title"></h1> 4 |5 P# H6 w! l0 s$ L+ j
    <div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
    ! ^7 m3 W  w* h8 i2 l: D    <p>This is news body</p>
    2 K. E5 P5 ]; T0 ?! H( d* j </div>
    6 ~$ T4 s5 j! O% n( U0 U
  • 在 common/js 中添加通用的 javscript 方法。                         . V% T- [9 Q6 u+ T9 T: k6 o
    ' i! H2 F% B2 V" `. Q/ r+ n  ?" g) k
    清单 5. loadView 方法
  • function loadView(id, url) { - `/ x# b6 e3 t" e/ `! u# I8 a! k& H
        var view = new dojox.mobile.ScrollableView({
    , U7 A, Y4 Z8 T3 W6 D$ x        id: id, - ^: p4 s8 C6 _: L' r& f7 ?) J
            selected: true
    ! O& Z; Y/ W% }, o% {% M( \    }); . T, c2 r- e" j% k/ ?: ]
        var contentPane = new dojox.mobile.ContentPane({
    # L' [6 T6 N* m5 H# m  }( }! {# T7 ]        href: url 9 r- u  Q, j$ J. r
        }); + \8 e% A- d6 w$ U" _% m. y
        view.addChild(contentPane); 5 a1 O1 Q% W6 C6 ]+ L! t
        return view;
    3 C7 ?9 l% F+ s% g7 B6 G }

    % |, M- a* t! g2 L7 f* q+ C# K

    : f: s, T4 e4 w
loadView 方法主要工作是把列表视图(list view)和正文视图(detail view)分别加载到一个 ScrollableView 当中。接下来我们开始创建两个不同的皮肤以及皮肤相关的代码。7 b% d) M9 {" I- X

8 H  j9 J4 B/ k6 f' E: l

: \$ b# y# }, f9 ]  k9 L& d  Z! G创建运行时皮肤
% z2 C$ \3 W2 @首先我们需要新建一个 Worklight 环境,右键 NewsApp 工程选择 New ->Worklight Environment, 如图 6 所示。
+ `. x* x# C' M) ?; M* O  A1 n: [( w6 \/ P6 e1 H! h: z- ~
图 6. 创建 Worklight 环境
0 G" F  c$ @- Z( j1 D0 g$ v! P; d* a6 W* T
Worklight 提供了多种手机平台环境,包括:iPhone/iPad, Android, BlackBerry 和 Windows Phone 等。在这里我们选择 Android phones and tablets,如图 7 所示。% V: h- V7 P/ b9 \. ?5 y( H. d( L; B

4 ?- x. f  ^1 n! X1 Y3 G图 7. 添加 Android phone and tablet 环境  P3 S( R; r( C" p
  R: B2 v4 x7 a9 o8 U& S" }
接下来我们创建两套运行时皮肤,一套针对 Android 手机,另外一套针对 Android 平板电脑。$ o3 R9 u9 g, |; U
右键 NewsApp 项目,选择 New -> Worklight Application Skin, 然后选择 Skin 对用的手机环境为之前创建的 Android phones and tablets, 输入 skin 的名字 android.phone, 如图 8 所示。
; A/ l4 ?! p2 D) H4 G5 X1 V( w* e+ |+ t
图 8. 添加 Android Phone 皮肤% _" {0 ^: u) r" z, x/ t0 p: |9 e  i
/ ?# b2 r6 W' W- {7 M0 _4 k% g2 ~/ P
同样地,我们创建另外一个皮肤,名称为 android.tablet. Worklight 会自动地将创建完的皮肤在 application-descriptor.xml 中注册,如清单 6 所示。这里需要注意一点,当我们删除某一个 skin 的时候,需要在 application descriptor 中手动删除该 skin 标签。
# c0 G( u0 L$ _- A# }  P, Y- a- {
7 `3 Y) u, ]: S& i5 L7 J清单 6. application-descriptor.xml 中注册的 skin 信息
  y& P+ e# r5 z. ?( D2 \
<android version="1.0"> & W) R' s7 g) s7 e
    <skins>
( o; k, j/ D5 Z) s        <skin name="default">
. W& Q3 Z9 S7 b0 T( ~5 a            <folder name="common"/> 1 _( B8 ^  s3 \
            <folder name="android"/> 0 i( p: q# |6 c. f5 f* H
    </skin>
( {7 c0 n. t- d# g/ Y6 J3 N    <skin name="android.phone">   L' J; t0 Z2 k
            <folder name="common"/>
1 h7 x% j, I' z) M4 d, u) z            <folder name="android"/>
2 L$ d& ?' V$ D6 T! R            <folder name="android.phone"/>
: X8 g! l; C( @( a0 ?        </skin> 0 J) a# b  u) I: u
        <skin name="android.tablet">
* e& k# R; v# e2 O' l: c            <folder name="common"/>
, V( Z/ _$ T; V! j+ r/ c! e& m            <folder name="android"/>
& z% M8 j  a  D  j            <folder name="android.tablet"/> 3 x0 M- L: r! t: _2 Q3 ~; H
        </skin>
' ?8 x( o3 j" i; w  j" Y- i; u </skins>
2 T% r/ `6 A7 A; b* t+ ]& j </android>

* n. c0 u; E% T( ^9 Q7 y每一个皮肤包含了各自的 css 文件,image 图片和 javascript 方法。我们需要为两个皮肤创建不同的初始化函数,把列表视图和正文视图按照特定的方式加载到主 html 文件中。) z) D3 A" [% h8 X- ]% C/ j6 t
  • 在 android.phone 的 js 文件夹下新建一个与 common/js 下同名的 js 文件:NewsApp.js,在这个文件里添加初始化函数。                        
    ) h  G$ I+ w- G- J2 f6 ?9 V9 h5 L. f" l) a0 y- a
    清单 7. phone 皮肤的初始化函数
  • function init() { # W0 a+ E2 D; u  M+ h+ u
        var listView = loadView("listView", "data/list.html");
    + a2 W" D# m* C: o    dojo.place(listView.domNode, dojo.body());
    " f! d$ y; X( e" {    var detailView = loadView("detailView", "data/detail.html"); - O# W: ?4 Z8 b& L1 _3 n" G
        dojo.place(detailView.domNode, dojo.body()); & S$ g5 J& M+ G# m: N( A: [" i
    }
    ) x9 z' M( d7 e  G  E$ x, h
    初始化函数把两个视图按顺序添加到主页面中,当程序启动时,显示第一个页面,也就是列表视图。当用户点击列表视图中的某一项,就会转到正文视图。
  • 同样地,我们在 android.tablet 的 js 文件夹下也新建一个 NewsApp.js,它的初始化函数如下:                          3 |( X1 W! a+ v8 v! J

    ' i- a  L4 u# k9 f8 @" \. ]清单 8. tablet 皮肤的初始化函数
  • function init() {
    1 V( w* v0 K% T; A5 k/ Q+ B* O1 c# _    var fixedSplitter = new dojox.mobile.FixedSplitter({
    ' F7 A3 t8 J; e" A! E    orientation: "H"& L* W" \: p; j, C* g# _8 p
        }, dojo.create("div", null, dojo.body(), 'first')); 6 G8 y, x6 S1 V4 L5 N! ?
        fixedSplitter.startup();
    . W8 c9 x8 B1 l  g8 Z8 l    var listView = loadView("listView", "data/list.html");
    - w2 e& s: K7 v& w: G& p4 q    var leftPane = new dojox.mobile.ContentPane({ 2 F. [( ^/ p, T3 o! l+ ]
        id: "leftPane", 1 l8 A; A6 k9 y( J$ |. x0 r
        content: listView.domNode
    # c/ G  s( {7 n9 [% \( `+ W: @    });
    9 o  X5 T* E9 R; S3 K    fixedSplitter.addChild(leftPane); 5 v6 }! W4 Z% R
        var detailView = loadView("detailView", "data/detail.html"); 5 t8 d4 P0 F2 c/ }" x# ^- ]
        var rightPane = new dojox.mobile.ContentPane({ " K7 o/ Q3 _  D& b7 q$ m
            id: "rightPane", ( X2 A9 K1 v( z
            content: detailView.domNode   }1 M2 J1 ?+ b4 y: j# E( ^
        });   r* C  T. P* Q- A- [1 P. W
        fixedSplitter.addChild(rightPane);
    - S5 O2 a' v+ s3 V }
    + S9 e2 z- l$ y0 a3 n8 b

    2 Y3 t' K2 D9 {* j! T
在这个初始化函数中,我们用到了 FixedSplitter 这个 dojo mobile 控件,它可以把 mobile 页面分为多个区域,每个区域可以加载不同的视图。这里我们把整个页面分成左右两块 leftPane 和 rightPane,分别加载列表视图和正文视图。+ k5 a" Z1 l; y
当我们完成不同皮肤的初始化函数之后,需要在 skinLoader.js 的 getSkinName 方法中添加根据移动设备屏幕大小动态选择皮肤的代码。如图 9 所示。
: f, }2 U- P+ b7 N* D0 Q- d# h
) }, Y! V/ r* J* }2 G7 m图 9. skinLoader.js; m8 S7 z  m& w1 N( @+ j
& z1 T$ @) F4 [- l6 Y6 I
2 B& }% C; c* h& J, H2 r4 o+ K3 D9 `
清单 9. getSkinName 方法
- `2 T* F$ K- U2 n* ]
                                  # E7 L5 G  d2 z: r+ J( M& S
function getSkinName() { ! C' @5 C  m& P$ n* T& ~( C( N
    var skinName = "android.phone";
( r3 K, Q! v4 \( g" D7 ^( p    var screenHeight = screen.height;
5 u8 r$ T! @9 ]/ w9 S* U( a    var screenWidth = screen.width;
! r$ Q/ A9 Q6 w8 y% R    if (screenHeight >= 1000 || screenWidth >= 1000) { . A! Q5 ~; l, r2 [8 W
        skinName = "android.tablet";
# ?6 x; a/ u5 p$ k    }
* e$ _. Y# M3 v# U5 V    return skinName;
, f& M( ]4 y" o1 A+ k4 a5 p }

) v3 w7 q( |* `/ {这个方法根据屏幕的大小来选择应用哪一个皮肤。注意 skinName 的值要跟创建的皮肤名称保持一致。
, h, n7 C) c; C1 B- ^

- a! \8 L% ]9 f6 k, ^& v
# R3 X) U* ^4 `5 e8 ?- q5 B皮肤应用效果
1 l! c- c6 T4 o& P$ t2 L1 }我们把 NewsApp 工程部署到 Worklight Server 上,然后分别在不同手机尺寸的模拟器上运行。图 10 所示的是运行在小屏幕手机上的效果。图 11 所示的是运行在大屏幕平板电脑上的效果。( a, W# R( W# e  H- o0 \1 \
! l2 E5 G" T' ~" k7 I% d* Z
图 10. 手机显示效果
$ L4 m( v6 P6 x0 M0 ]' ^2 f! d1 B# C1 T) J

3 [7 P2 S" y! v" ^2 B+ O" W: y图 11. 平板电脑显示效果4 U- B: q+ Z3 J$ L  V, Q
$ A% Q' v; F0 M/ w


5 g. T2 X8 a) @8 s
. P2 }9 c/ M1 C! s: f7 L结束语( \, a+ S+ z* E7 H
运行时皮肤是 Worklight 的一个重要特性,它可以方便地在同一个应用程序中添加多个皮肤外观,在程序运行时动态地选择适合移动终端设备的皮肤。本文从一个具体的实例出发,帮助读者了解运行时皮肤的具体使用方法。
5 P' {  r" t" |1 s5 O  p  w6 x6 y. V8 G/ P" q2 t

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
 楼主| 发表于 2013-2-17 10:51:25 | 显示全部楼层
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|手机版|无图版|SCMLife.com ( 京ICP备06056490号-1 )

GMT+8, 2018-1-18 00:00 , Processed in 0.078631 second(s), 7 queries , Gzip On, MemCache On.

Powered by SCMLife X3.4 Licensed

© 2001-2017 JoyShare.

快速回复 返回顶部 返回列表