移动混合应用Hybrid App开发实战
移动混合应用Hybrid App开发实战
【引言】近年来随着移动设备类型的变多,操作系统的变多,用户需求的增加,对于每个项目启动前,大家都会考虑到的成本,团队成员,技术成熟度,时间,项目需求等一堆的因素。因此,开发App的方案已经变得越来越多了。曾经有一段HTML5的小浪潮,无数的人参与或者看到过一个讨论:原生开发还是混合开发,又或者是Web开发?到底最佳实践是怎样的,笔者认为只有实践过的人才会知道。尤其是在这个充满各种变数的移动互联网时代。
【摘要】笔者将从Hybrid App的开发现状出发,阐述Hybrid App的优缺点,同时对比Hybrid App与Native App的各自特性,最后探讨一下Hybrid App的新思想方向。
Hybrid App现状分析
Web App
毫无疑问Web App就是成本最低,最快速地解决方案了。尤其是近两年非常流行的响应式设计,Web App市场提供了非常好的实践场地。最近典型的Web App最佳案例是Sun天气应用了,其细节处理让人赞不绝口。
一般来说,拥有下面特点的就是一个Web App了:使用浏览器运行;纯Web前端架构,很多重要手机特性无法访问,例如联系人以及Push notification之类的;Single Page App;销售渠道多限于浏览器。
Hybrid App
所谓的Hybrid App其实会有不同的分支。而且会和Native应用有重合的地方。下面就说三种不同的解决方案。
方案一:使用PhoneGap、AppCan之类的中间件,以WebView作为用户界面层,以Javascript作为基本逻辑,以及和中间件通讯,再由中间件访问底层API的方式,进行应用开发。这种架构一般会非常依赖WebView层的性能。
方案二:使用Adobe Air、RubyMotion、Appcelerator或者是Xamarin这种非官方语言的工具,打包成原生应用的方式开发。为什么笔者会将它们定义为Hybrid App,主要是它们并没有很单纯地使用原生提供的语言进行开发,而是通过对开发者提供友好的开发工具,并折中地把这种开发语言转换成原生语言,最终打包出整个应用,所以也属于混合应用范畴。
方案三:在开发原生应用的基础上,嵌入WebView但是整体的架构使用原生应用提供,一般这样的开发由Native开发人员和Web前端开发人员组成。Native开发人员会写好基本的架构以及API让Web开发人员开发界面以及大部分的渲染。保证到交互设计,以及开发都有一个比较折中的效果出来,优化得好也会有很棒的效果。(当年Facebook Three20就使用该方案)
因此,Hybrid App有以下的特性:
1.开发时可能不采用或者大部分不采用原生语言,但是却有所有原生应用的特性;
2.架构方案会和原生有出入,基本由工具而定;
3.具有跨平台特性;
4.一般开发相对原生开发的方式要简单。
Native App
Native App毫无疑问是最可靠的方案。但是学习成本,人才成本,开发效率以及照顾不同平台的特性去考虑,都成为了开发人员心目中的一道坎。至于说这道坎是不可逾越的还是一道让你提高的坎,笔者觉得完全取决于你自己。基于种种因素的考虑,估计很多人就会选择折中的方案到了Hybrid App的开发行列当中,包括笔者自己也是这样过来的。
下面更多的内容都将围绕Hybrid App开发展开讨论。
Hybrid App在开发当中的优点和缺点
在Hybrid App的开发过程中,几种不同的方案笔者都有经历过。当然也经历到了Native App的开发阶段。在如此纠结复杂的过程中给了笔者不少的经验,下面笔者也会就自身的经验和大家分享这些方案当中的优缺点。对于初入行的朋友,笔者是从Web前端入行的,毕竟门槛较低,而且能够快速地培养自己的信心以及对代码的感觉。深入后就开始接触到移动开发这块了。所以会先从Hybrid App的第一种方案说起吧。
方案一(Web架构为重)
优点:
1.全Web开发,一定程度上有利于Web前端技术人员快速地构建页面样式;
2.有利于在不同的平台上面展示同一个交互层;
3.便于调试,开发的时候可以通过浏览器的方式进行调试,工具丰富。
缺点:
1.虽然说你可以专注在界面以及交互开发上了,但是这页会成为一个缺点,比如说要仿造一个iOS的默认设置界
面,就需要大量的html以及css代码了,而且效果不一定和iPhone上面的界面一样好;
2.正因为这是跨平台的开发,所以还是这句话:兼容是前端的痛。了解过在Android机器上面的Web开发就知道
这个痛了。比如前些年在Android设备上面写圆角,border-radius:10px,在Android的设备上面会出现毛边。
3.便于调试其实是在Web界面层的。但是实际上做Hybrid App开发的时候,你会遇到需求,进入手机的底层请求,
做某些处理。比如说如果该应用有Push Notification服务的话,你就需要到底层,获取Push Notification发生时的数据,以及做相应的交互处理。当然类似PhoneGap这类框架,已经有很好的插件机制去帮助你解决类似的问题,当然还有Game Center之类的插件,具体的话可以到Github去关注PhoneGap官方的账户,资源非常丰富;
方案二(编译转换方式)
优点:
1.利用自己熟悉的语言,进行应用开发,比如RubyMotion,就是使用Ruby语言去做iOS开发,开发起来的话,
代码量是数量级地下降啊。
2.部分开发工具提供跨平台的功能,让你的应用能够快速地发布到不同的平台上面。比如Mono社区的Xamarin,
就是典型的例子了。使用C#语言,能够把你的应用发布到iOS,Android以及WinPhone市场上面;
3.开发出来的程序运行高效。大部分这种架构的应用,其实还是非常依赖底层的东西的,而且包括界面的东西,
都是使用原生的API,效率就当然要比类似于PhoneGap这种架构要好了;
严重依赖于其工具厂商提供的工具包,调试的时候就要有全套的工具。当然一般来说这些厂商都会以收费的形式发布他们的工具,相应的也有客服提供技术支持。遇到系统升级,第三方sdk升级,开发工具出现bug等,那么就要等待工具厂商解决了。相当于把风险压在对方身上了,自己却要承担责任。
方案三(Native架构为重)
优点:
1.这无疑是最稳定的Hybrid App开发方式了,交互层的效率上由Native的东西解决了,而且架构上基本就是在App
内写网页,连App Store都是采用了该种方案;
2.开发时分工非常明确,底层的由iOS开发人员处理,上层的由Web前端开发人员处理;
3.有效的在线参数配置方式,以便于及时在线替换界面;
缺点:
1.团队至少需要两个工程师,一个是Web的,一个是iOS的。当然如果开发人员会两种技术也可独立承担;
2.还是运行效率,要权衡好多少界面采用Web来渲染,毕竟WebView的效率会相对降低,以前Facebook就是因
为Web的渲染效率低下,把整个应用改为原生的解决方案。当然这里面可以通过优化来解决。但是优化也是有限度的,如Ruby创始人Matz所说优化要恰当(包括花的时间,技巧等),而且有时候的优化达到的回报率不一定达到你自己的期望。
Hybrid App和Native App开发对比
因为方案三中的思想基本上就是原生应用的开发思想了。这里要做的对比应该不算大,因此笔者不会做太多的阐述介绍两者的不同。但是如果是偏重Web架构的,或者是以方案二这种透过特殊工具开发的,就和原生开发有对比了。这次笔者暂时会以方案一拿来讨论。讨论中主要会以架构,代码管理上来讨论,当然也会说到部分细节。
架构讨论:
因为这是偏重于Web开发的应用,这里面就需要开发人员有很强烈的大型Web前端架构思想在里面。提到这里可能马上浮现在你脑海中的词语就是:angular.js,require.js,sea.js,backbone.js等。没错,这些工具都能够帮助你快速地梳理好思路,管理好你的Web应用。对开发者最友好的,发挥空间最大的非PhoneGap莫属了。所以笔者就会以PhoneGap 应用展开讨论。(因为类似Sencha也有提供方案,但是Sencha本身是一个重量级的框架,而且有自己的思想在里头,加上他本身也提供开发工具,在这里就不适合讨论了。对于开发者来说可以根据自己的需求选择好工具)
从工具上看:
Angular.js
用于双向绑定,网络请求,视图管理等工作。
javascript模块化工具,在使用较多的交互对象,PhoneGap插件的时候,你就会发现一个强大的模块化工具会在开发的时候提供极好的帮助。能够帮助你把整体的代码,管理得井井有条。
Jade Template Engine
模板引擎。笔者个人比较推荐使用Jade,而且笔者本人也在博客中多次写到Jade在不同场景下使用的技巧的有关文章。主要是jade的语法太简洁了,而且面向JS开发人员非常友好。如果你还没有开始使用模板引擎,赶紧加入这个队列吧,你已经落后了。
Jquery Mobile
如果你暂时还没有一个设计师,但是又急于构造一个应用出来。jquery mobile就提供了多套不同风格的模板,供你使用,而且还含有不同的交互动画等。而且也是跨平台的。当然实际场景中,笔者觉得你会花很多时间在写css 上面,因为设计总是天马行空的。当然你还有很多工具啦,例如sass,以及less.js等。
PhoneGap.js或者Cordova.js
做Phonegap开发必须使用的代码库,用于和PhoneGap框架通讯。现在这个库已经改名了,是Cordova。具体为什么改名,得问Adobe咯。
PhoneGap Plugins
PhoneGap的插件能够帮助你快速地抵达手机的其他API上面,直接使用Javascript来操控这些底层的API。例如调用Push Notification的相应发生的事件。
从代码目录上面看混合应用中的Web层:
1. /js
2. mainView.js
3. settingView.js
4. networkObject.js
5. renderObject.js
6.
7. /lib
8. /PhoneGapPlugins
9. push-notification-plugin.js
10. pickerView.js
11. PhoneGap.js
12. zepto.js
13. jquerymobile.js
14. iscroll.js
15. angular.js
16. jade.js
17.
18. /css
19. /mainView
20. listItemTemplate.css
21. questionListTemplate.css
22. /settingView
23. /personView
24. /layout
25. navigationBar.css
26. tabButton.css
27. app.css
28.
29. /template
30. /mainView
31. listItemTemplate.txt
32. questionListTemplate.txt
33. /settingView
34. /personView
35. /layout
36. navigationBarTemplate.txt
37. tabButtonTemplate.txt
38.
39. index.html
40. app.js
41. require.js
从代码的目录上面看,就是经典的静态网页文件的目录,非常简单。下面就用一句话来说说整个应用的运作过程吧:
打开PhoneGap应用->进入index.html ->运行require.js ->加载应用资源-> app.js 控制整个应用-> angular.js 进行事件绑定以及视图渲染->视图渲染的时候会将数据和加载好的视图模板(template目录下的代码)处理->经过jade模板引擎->渲染到相应的位置上
就是如此简单。
看完了简单的PhoneGap应用后,笔者们来看看简单iOS应用在开发时候的代码目录吧。思路上还是非常相似的。在这里面,笔者不会深入代码部分去讨论具体的实现以及细节上的东西。
1. demoApp
2. /Resource
3. navigationBar.png
4. navigationBar@2x.png
5. /demoApp
6. AppDelegate.h
7. AppDelegate.m
8. /SettingViewController
9. settingViewController.h
10. settingViewController.m
11. /MainViewController
12. mainViewController.h
13. mainViewController.m
14. /Supporting Files
15. demoApp-Info.plist
16. InfoPlist.strings
17. ...
18. /plugin
19. /AFNetworking
20. AFHTTPClient.h
21. AFHTTPClient.m
22. AFHTTPRequestOperation.h
23. AFHTTPRequestOperation.m
24. ...
25. /Frameworks
26. CoreData.framework
27. UIKit.framework
28. /Products
29. demoApp.app
Objective-C 是一种通用、高级、面向对象的编程语言。Objective-C是承自Smalltalk的信息传递模型(message passing)。Objective-C里,与其说对象互相调用方法,不如说对象之间互相传递信息更为精确。Objective-C强调面对对象编程,且Objective-C中强制要求将类的(interface)与实现(implementation)分为两个部分。类的定义文件遵循C语言之惯例以.h 为后缀,实现文件以.m 为后缀。所以你会看到大量的类文件在里头,整个工程就是有不同的类构成的。(当然可能这么描述不太准确,但是便于大家理解)
这就和丰富的Web前端有很大区别了,在Web前端开发里有HTML,CSS,JS三剑客,必须要用好这三个东西才可以把整个应用才可构建出来。但是在Native应用中,就很单一了。你只需要把握好Objective-C就可以了。因此对于原生应用来说,开发时只要遵守好规范,即使是一个新手参与开发,也可以快速地上手,看懂代码。因为模式已经定好,大家使用同一套的API。按着流程走就好了。当然学习Objective-C需要过程,但是对于拥有C语言,Java语言经验的开发者来说,是非常简单的事情。
当然,原生开发的缺点也很明显了,就是满足不了你的跨平台需求。
从代码目录上面看,其实也基本上看到笔者为什么使用多种JS库以及框架的原因了。主要的目的就是为了构建一个可维护的,具有规范性的Web应用。因为本身Javascript这门语言非常灵活,100个人可以具有100种风格,加上没有专门对于Javascript开设的课程,在过往都容易存在对这门语言的误解。基于种种的原因,就要约束好一个应用的代码风格,架构。此外,Javascript本身没有类的概念,所以在Javascript的面向对象编程中:Javascript的数据和成员封装很简单。没有类,完全是对象操作。这和Objective-C有很大不同。这个时候必须要有一种心态处理好整个Web应用:就是尽可能地抽象成对象,你的工作就是对象与对象之间存在交流。
另外有一些点是值得开发者注意的。对于原生应用来说,不管是iOS的,还是Android的,都会提供一套原生界面的库。以Objective-C 为例子。如果笔者需要调用Alert,笔者只需要编写:UIAlertView * alertView = [[UIAlertViewalloc]init];,
就把这个view声明好了。再去执行相应的方法,就可以了。但是对于Web应用来说,就需要编写