移動(dòng)混合應(yīng)用Hybrid App開(kāi)發(fā)實(shí)戰(zhàn)
【引言】近年來(lái)隨著移動(dòng)設(shè)備類(lèi)型的變多,操作系統(tǒng)的變多,用戶需求的增加,對(duì)于每個(gè)項(xiàng)目啟動(dòng)前,大家都會(huì)考慮到的成本,團(tuán)隊(duì)成員,技術(shù)成熟度,時(shí) 間,項(xiàng)目需求等一堆的因素。因此,開(kāi)發(fā)App的方案已經(jīng)變得越來(lái)越多了。曾經(jīng)有一段HTML5的小浪潮,無(wú)數(shù)的人參與或者看到過(guò)一個(gè)討論:原生開(kāi)發(fā)還是混 合開(kāi)發(fā),又或者是Web開(kāi)發(fā)?到底***實(shí)踐是怎樣的,筆者認(rèn)為只有實(shí)踐過(guò)的人才會(huì)知道。尤其是在這個(gè)充滿各種變數(shù)的移動(dòng)互聯(lián)網(wǎng)時(shí)代。
【摘要】筆者將從Hybrid App的開(kāi)發(fā)現(xiàn)狀出發(fā),闡述Hybrid App的優(yōu)缺點(diǎn),同時(shí)對(duì)比Hybrid App與Native App的各自特性,***探討一下Hybrid App的新思想方向。
Hybrid App現(xiàn)狀分析
Web App
毫無(wú)疑問(wèn)Web App就是成本***,最快速地解決方案了。尤其是近兩年非常流行的響應(yīng)式設(shè)計(jì),Web App市場(chǎng)提供了非常好的實(shí)踐場(chǎng)地。最近典型的Web App***案例是Sun天氣應(yīng)用了,其細(xì)節(jié)處理讓人贊不絕口。
一般來(lái)說(shuō),擁有下面特點(diǎn)的就是一個(gè)Web App了:使用瀏覽器運(yùn)行;純Web前端架構(gòu),很多重要手機(jī)特性無(wú)法訪問(wèn),例如聯(lián)系人以及Push notification之類(lèi)的;Single Page App;銷(xiāo)售渠道多限于瀏覽器。
Hybrid App
所謂的Hybrid App其實(shí)會(huì)有不同的分支。而且會(huì)和Native應(yīng)用有重合的地方。下面就說(shuō)三種不同的解決方案。
方案一:使用PhoneGap、AppCan之類(lèi)的中間件,以WebView作為用戶界面層,以Javascript作為基本邏輯,以及和中間件通訊,再由中間件訪問(wèn)底層API的方式,進(jìn)行應(yīng)用開(kāi)發(fā)。這種架構(gòu)一般會(huì)非常依賴WebView層的性能。
方案二:使用Adobe Air、RubyMotion、Appcelerator或者是Xamarin這種非官方語(yǔ)言的工具,打包成原生應(yīng)用的方式開(kāi)發(fā)。為什么筆者會(huì)將它們定義 為Hybrid App,主要是它們并沒(méi)有很單純地使用原生提供的語(yǔ)言進(jìn)行開(kāi)發(fā),而是通過(guò)對(duì)開(kāi)發(fā)者提供友好的開(kāi)發(fā)工具,并折中地把這種開(kāi)發(fā)語(yǔ)言轉(zhuǎn)換成原生語(yǔ)言,最終打包出 整個(gè)應(yīng)用,所以也屬于混合應(yīng)用范疇。
方案三:在開(kāi)發(fā)原生應(yīng)用的基礎(chǔ)上,嵌入WebView但是整體的架構(gòu)使用原生應(yīng)用提供,一般這樣的開(kāi)發(fā)由Native開(kāi)發(fā)人員和Web前端開(kāi)發(fā)人員 組成。Native開(kāi)發(fā)人員會(huì)寫(xiě)好基本的架構(gòu)以及API讓W(xué)eb開(kāi)發(fā)人員開(kāi)發(fā)界面以及大部分的渲染。保證到交互設(shè)計(jì),以及開(kāi)發(fā)都有一個(gè)比較折中的效果出 來(lái),優(yōu)化得好也會(huì)有很棒的效果。(當(dāng)年Facebook Three20就使用該方案)
因此,Hybrid App有以下的特性:
- 開(kāi)發(fā)時(shí)可能不采用或者大部分不采用原生語(yǔ)言,但是卻有所有原生應(yīng)用的特性;
- 架構(gòu)方案會(huì)和原生有出入,基本由工具而定;
- 具有跨平臺(tái)特性;
- 一般開(kāi)發(fā)相對(duì)原生開(kāi)發(fā)的方式要簡(jiǎn)單。
Native App
Native App毫無(wú)疑問(wèn)是最可靠的方案。但是學(xué)習(xí)成本,人才成本,開(kāi)發(fā)效率以及照顧不同平臺(tái)的特性去考慮,都成為了開(kāi)發(fā)人員心目中的一道坎。至于說(shuō)這道坎是不可逾 越的還是一道讓你提高的坎,筆者覺(jué)得完全取決于你自己?;诜N種因素的考慮,估計(jì)很多人就會(huì)選擇折中的方案到了Hybrid App的開(kāi)發(fā)行列當(dāng)中,包括筆者自己也是這樣過(guò)來(lái)的。
下面更多的內(nèi)容都將圍繞Hybrid App開(kāi)發(fā)展開(kāi)討論。
Hybrid App在開(kāi)發(fā)當(dāng)中的優(yōu)點(diǎn)和缺點(diǎn)
在Hybrid App的開(kāi)發(fā)過(guò)程中,幾種不同的方案筆者都有經(jīng)歷過(guò)。當(dāng)然也經(jīng)歷到了Native App的開(kāi)發(fā)階段。在如此糾結(jié)復(fù)雜的過(guò)程中給了筆者不少的經(jīng)驗(yàn),下面筆者也會(huì)就自身的經(jīng)驗(yàn)和大家分享這些方案當(dāng)中的優(yōu)缺點(diǎn)。對(duì)于初入行的朋友,筆者是從 Web前端入行的,畢竟門(mén)檻較低,而且能夠快速地培養(yǎng)自己的信心以及對(duì)代碼的感覺(jué)。深入后就開(kāi)始接觸到移動(dòng)開(kāi)發(fā)這塊了。所以會(huì)先從Hybrid App的***種方案說(shuō)起吧。
方案一(Web架構(gòu)為重)
優(yōu)點(diǎn):
- 全Web開(kāi)發(fā),一定程度上有利于Web前端技術(shù)人員快速地構(gòu)建頁(yè)面樣式;
- 有利于在不同的平臺(tái)上面展示同一個(gè)交互層;
- 便于調(diào)試,開(kāi)發(fā)的時(shí)候可以通過(guò)瀏覽器的方式進(jìn)行調(diào)試,工具豐富。
缺點(diǎn):
- 雖然說(shuō)你可以專(zhuān)注在界面以及交互開(kāi)發(fā)上了,但是這頁(yè)會(huì)成為一個(gè)缺點(diǎn),比如說(shuō)要仿造一個(gè)iOS的默認(rèn)設(shè)置界面,就需要大量的html以及css代碼了,而且效果不一定和iPhone上面的界面一樣好;
- 正因?yàn)檫@是跨平臺(tái)的開(kāi)發(fā),所以還是這句話:兼容是前端的痛。了解過(guò)在Android機(jī)器上面的Web開(kāi)發(fā)就知道這個(gè)痛了。比如前些年在Android設(shè)備上面寫(xiě)圓角,border-radius:10px,在Android的設(shè)備上面會(huì)出現(xiàn)毛邊。
- 便于調(diào)試其實(shí)是在Web界面層的。但是實(shí)際上做Hybrid App開(kāi)發(fā)的時(shí)候,你會(huì)遇到需求,進(jìn)入手機(jī)的底層請(qǐng)求,做某些處理。比如說(shuō)如果該應(yīng)用有Push Notification服務(wù)的話,你就需要到底層,獲取Push Notification發(fā)生時(shí)的數(shù)據(jù),以及做相應(yīng)的交互處理。當(dāng)然類(lèi)似PhoneGap這類(lèi)框架,已經(jīng)有很好的插件機(jī)制去幫助你解決類(lèi)似的問(wèn)題,當(dāng)然還 有Game Center之類(lèi)的插件,具體的話可以到Github去關(guān)注PhoneGap官方的賬戶,資源非常豐富;
方案二(編譯轉(zhuǎn)換方式)
優(yōu)點(diǎn):
- 利用自己熟悉的語(yǔ)言,進(jìn)行應(yīng)用開(kāi)發(fā),比如RubyMotion,就是使用Ruby語(yǔ)言去做iOS開(kāi)發(fā),開(kāi)發(fā)起來(lái)的話,代碼量是數(shù)量級(jí)地下降啊。
- 部分開(kāi)發(fā)工具提供跨平臺(tái)的功能,讓你的應(yīng)用能夠快速地發(fā)布到不同的平臺(tái)上面。比如Mono社區(qū)的Xamarin,就是典型的例子了。使用C#語(yǔ)言,能夠把你的應(yīng)用發(fā)布到iOS,Android以及WinPhone市場(chǎng)上面;
- 開(kāi)發(fā)出來(lái)的程序運(yùn)行高效。大部分這種架構(gòu)的應(yīng)用,其實(shí)還是非常依賴底層的東西的,而且包括界面的東西,都是使用原生的API,效率就當(dāng)然要比類(lèi)似于PhoneGap這種架構(gòu)要好了;
缺點(diǎn):
嚴(yán)重依賴于其工具廠商提供的工具包,調(diào)試的時(shí)候就要有全套的工具。當(dāng)然一般來(lái)說(shuō)這些廠商都會(huì)以收費(fèi)的形式發(fā)布他們的工具,相應(yīng)的也有客服提供技術(shù)支 持。遇到系統(tǒng)升級(jí),第三方sdk升級(jí),開(kāi)發(fā)工具出現(xiàn)bug等,那么就要等待工具廠商解決了。相當(dāng)于把風(fēng)險(xiǎn)壓在對(duì)方身上了,自己卻要承擔(dān)責(zé)任。
方案三(Native架構(gòu)為重)
優(yōu)點(diǎn):
- 這無(wú)疑是最穩(wěn)定的Hybrid App開(kāi)發(fā)方式了,交互層的效率上由Native的東西解決了,而且架構(gòu)上基本就是在App內(nèi)寫(xiě)網(wǎng)頁(yè),連App Store都是采用了該種方案;
- 開(kāi)發(fā)時(shí)分工非常明確,底層的由iOS開(kāi)發(fā)人員處理,上層的由Web前端開(kāi)發(fā)人員處理;
- 有效的在線參數(shù)配置方式,以便于及時(shí)在線替換界面;
缺點(diǎn):
- 團(tuán)隊(duì)至少需要兩個(gè)工程師,一個(gè)是Web的,一個(gè)是iOS的。當(dāng)然如果開(kāi)發(fā)人員會(huì)兩種技術(shù)也可獨(dú)立承擔(dān);
- 還是運(yùn)行效率,要權(quán)衡好多少界面采用Web來(lái)渲染,畢竟WebView的效率會(huì)相對(duì)降低,以前Facebook就是因?yàn)閃eb的渲染效率 低下,把整個(gè)應(yīng)用改為原生的解決方案。當(dāng)然這里面可以通過(guò)優(yōu)化來(lái)解決。但是優(yōu)化也是有限度的,如Ruby創(chuàng)始人Matz所說(shuō)優(yōu)化要恰當(dāng)(包括花的時(shí)間,技 巧等),而且有時(shí)候的優(yōu)化達(dá)到的回報(bào)率不一定達(dá)到你自己的期望。
Hybrid App和Native App開(kāi)發(fā)對(duì)比
因?yàn)榉桨溉械乃枷牖旧暇褪窃鷳?yīng)用的開(kāi)發(fā)思想了。這里要做的對(duì)比應(yīng)該不算大,因此筆者不會(huì)做太多的闡述介紹兩者的不同。但是如果是偏重Web架 構(gòu)的,或者是以方案二這種透過(guò)特殊工具開(kāi)發(fā)的,就和原生開(kāi)發(fā)有對(duì)比了。這次筆者暫時(shí)會(huì)以方案一拿來(lái)討論。討論中主要會(huì)以架構(gòu),代碼管理上來(lái)討論,當(dāng)然也會(huì) 說(shuō)到部分細(xì)節(jié)。
架構(gòu)討論:
因?yàn)檫@是偏重于Web開(kāi)發(fā)的應(yīng)用,這里面就需要開(kāi)發(fā)人員有很強(qiáng)烈的大型Web前端架構(gòu)思想在里面。提到這里可能馬上浮現(xiàn)在你腦海中的詞語(yǔ)就 是:angular.js,require.js,sea.js,backbone.js等。沒(méi)錯(cuò),這些工具都能夠幫助你快速地梳理好思路,管理好你的 Web應(yīng)用。對(duì)開(kāi)發(fā)者最友好的,發(fā)揮空間***的非PhoneGap莫屬了。所以筆者就會(huì)以PhoneGap應(yīng)用展開(kāi)討論。(因?yàn)轭?lèi)似Sencha也有提供 方案,但是Sencha本身是一個(gè)重量級(jí)的框架,而且有自己的思想在里頭,加上他本身也提供開(kāi)發(fā)工具,在這里就不適合討論了。對(duì)于開(kāi)發(fā)者來(lái)說(shuō)可以根據(jù)自己 的需求選擇好工具)
從工具上看:
用于雙向綁定,網(wǎng)絡(luò)請(qǐng)求,視圖管理等工作。
javascript模塊化工具,在使用較多的交互對(duì)象,PhoneGap插件的時(shí)候,你就會(huì)發(fā)現(xiàn)一個(gè)強(qiáng)大的模塊化工具會(huì)在開(kāi)發(fā)的時(shí)候提供極好的幫助。能夠幫助你把整體的代碼,管理得井井有條。
模板引擎。筆者個(gè)人比較推薦使用Jade,而且筆者本人也在博客中多次寫(xiě)到Jade在不同場(chǎng)景下使用的技巧的有關(guān)文章。主要是jade的語(yǔ)法太簡(jiǎn)潔了,而且面向JS開(kāi)發(fā)人員非常友好。如果你還沒(méi)有開(kāi)始使用模板引擎,趕緊加入這個(gè)隊(duì)列吧,你已經(jīng)落后了。
如果你暫時(shí)還沒(méi)有一個(gè)設(shè)計(jì)師,但是又急于構(gòu)造一個(gè)應(yīng)用出來(lái)。jquery mobile就提供了多套不同風(fēng)格的模板,供你使用,而且還含有不同的交互動(dòng)畫(huà)等。而且也是跨平臺(tái)的。當(dāng)然實(shí)際場(chǎng)景中,筆者覺(jué)得你會(huì)花很多時(shí)間在寫(xiě)css 上面,因?yàn)樵O(shè)計(jì)總是天馬行空的。當(dāng)然你還有很多工具啦,例如sass,以及l(fā)ess.js等。
PhoneGap.js或者Cordova.js
做Phonegap開(kāi)發(fā)必須使用的代碼庫(kù),用于和PhoneGap框架通訊?,F(xiàn)在這個(gè)庫(kù)已經(jīng)改名了,是Cordova。具體為什么改名,得問(wèn)Adobe咯。
PhoneGap的插件能夠幫助你快速地抵達(dá)手機(jī)的其他API上面,直接使用Javascript來(lái)操控這些底層的API。例如調(diào)用Push Notification的相應(yīng)發(fā)生的事件。
從代碼目錄上面看混合應(yīng)用中的Web層:
- /js
- mainView.js
- settingView.js
- networkObject.js
- renderObject.js
- /lib
- /PhoneGapPlugins
- push-notification-plugin.js
- pickerView.js
- PhoneGap.js
- zepto.js
- jquerymobile.js
- iscroll.js
- angular.js
- jade.js
- /css
- /mainView
- listItemTemplate.css
- questionListTemplate.css
- /settingView
- /personView
- /layout
- navigationBar.css
- tabButton.css
- app.css
- /template
- /mainView
- listItemTemplate.txt
- questionListTemplate.txt
- /settingView
- /personView
- /layout
- navigationBarTemplate.txt
- tabButtonTemplate.txt
- index.html
- app.js
- require.js
從代碼的目錄上面看,就是經(jīng)典的靜態(tài)網(wǎng)頁(yè)文件的目錄,非常簡(jiǎn)單。下面就用一句話來(lái)說(shuō)說(shuō)整個(gè)應(yīng)用的運(yùn)作過(guò)程吧:
打開(kāi)PhoneGap應(yīng)用 ->進(jìn)入 index.html ->運(yùn)行require.js ->加載應(yīng)用資源 -> app.js 控制整個(gè)應(yīng)用 -> angular.js 進(jìn)行事件綁定以及視圖渲染 ->視圖渲染的時(shí)候會(huì)將數(shù)據(jù)和加載好的視圖模板(template目錄下的代碼)處理 ->經(jīng)過(guò)jade模板引擎 ->渲染到相應(yīng)的位置上
就是如此簡(jiǎn)單。
看完了簡(jiǎn)單的PhoneGap應(yīng)用后,筆者們來(lái)看看簡(jiǎn)單iOS應(yīng)用在開(kāi)發(fā)時(shí)候的代碼目錄吧。思路上還是非常相似的。在這里面,筆者不會(huì)深入代碼部分去討論具體的實(shí)現(xiàn)以及細(xì)節(jié)上的東西。
- demoApp
- /Resource
- navigationBar.png
- navigationBar@2x.png
- /demoApp
- AppDelegate.h
- AppDelegate.m
- /SettingViewController
- settingViewController.h
- settingViewController.m
- /MainViewController
- mainViewController.h
- mainViewController.m
- /Supporting Files
- demoApp-Info.plist
- InfoPlist.strings
- ...
- /plugin
- /AFNetworking
- AFHTTPClient.h
- AFHTTPClient.m
- AFHTTPRequestOperation.h
- AFHTTPRequestOperation.m
- ...
- /Frameworks
- CoreData.framework
- UIKit.framework
- /Products
- demoApp.app
Objective-C 是一種通用、高級(jí)、面向?qū)ο蟮木幊陶Z(yǔ)言。Objective-C是承自Smalltalk的信息傳遞模型(message passing)。Objective-C里,與其說(shuō)對(duì)象互相調(diào)用方法,不如說(shuō)對(duì)象之間互相傳遞信息更為精確。Objective-C強(qiáng)調(diào)面對(duì)對(duì)象編程, 且Objective-C中強(qiáng)制要求將類(lèi)的(interface)與實(shí)現(xiàn)(implementation)分為兩個(gè)部分。類(lèi)的定義文件遵循C語(yǔ)言之慣例以 .h 為后綴,實(shí)現(xiàn)文件以 .m 為后綴。所以你會(huì)看到大量的類(lèi)文件在里頭,整個(gè)工程就是有不同的類(lèi)構(gòu)成的。(當(dāng)然可能這么描述不太準(zhǔn)確,但是便于大家理解)
這就和豐富的Web前端有很大區(qū)別了,在Web前端開(kāi)發(fā)里有HTML,CSS,JS三劍客,必須要用好這三個(gè)東西才可以把整個(gè)應(yīng)用才可構(gòu)建出來(lái)。但 是在Native應(yīng)用中,就很單一了。你只需要把握好Objective-C就可以了。因此對(duì)于原生應(yīng)用來(lái)說(shuō),開(kāi)發(fā)時(shí)只要遵守好規(guī)范,即使是一個(gè)新手參與 開(kāi)發(fā),也可以快速地上手,看懂代碼。因?yàn)槟J揭呀?jīng)定好,大家使用同一套的API。按著流程走就好了。當(dāng)然學(xué)習(xí)Objective-C需要過(guò)程,但是對(duì)于擁 有C語(yǔ)言,Java語(yǔ)言經(jīng)驗(yàn)的開(kāi)發(fā)者來(lái)說(shuō),是非常簡(jiǎn)單的事情。
當(dāng)然,原生開(kāi)發(fā)的缺點(diǎn)也很明顯了,就是滿足不了你的跨平臺(tái)需求。
從代碼目錄上面看,其實(shí)也基本上看到筆者為什么使用多種JS庫(kù)以及框架的原因了。主要的目的就是為了構(gòu)建一個(gè)可維護(hù)的,具有規(guī)范性的Web應(yīng)用。因 為本身Javascript這門(mén)語(yǔ)言非常靈活,100個(gè)人可以具有100種風(fēng)格,加上沒(méi)有專(zhuān)門(mén)對(duì)于Javascript開(kāi)設(shè)的課程,在過(guò)往都容易存在對(duì)這 門(mén)語(yǔ)言的誤解。基于種種的原因,就要約束好一個(gè)應(yīng)用的代碼風(fēng)格,架構(gòu)。此外,Javascript本身沒(méi)有類(lèi)的概念,所以在Javascript的面向?qū)?象編程中:Javascript的數(shù)據(jù)和成員封裝很簡(jiǎn)單。沒(méi)有類(lèi),完全是對(duì)象操作。這和Objective-C有很大不同。這個(gè)時(shí)候必須要有一種心態(tài)處理 好整個(gè)Web應(yīng)用:就是盡可能地抽象成對(duì)象,你的工作就是對(duì)象與對(duì)象之間存在交流。
另外有一些點(diǎn)是值得開(kāi)發(fā)者注意的。對(duì)于原生應(yīng)用來(lái)說(shuō),不管是iOS的,還是Android的,都會(huì)提供一套原生界面的庫(kù)。以O(shè)bjective-C 為例子。如果筆者需要調(diào)用Alert,筆者只需要編寫(xiě):UIAlertView * alertView = [[UIAlertViewalloc]init];,就把這個(gè)view聲明好了。再去執(zhí)行相應(yīng)的方法,就可以了。但是對(duì)于Web應(yīng)用來(lái)說(shuō),就需要編 寫(xiě)<div id='alertView'><button>確定</button></div><script& gt;$('#alertView').show();</script>
,一堆的css代碼和html代碼去實(shí)現(xiàn)。當(dāng)然你會(huì)詢問(wèn)筆者,直接寫(xiě) alert() 不就可以了嗎?要是真這么簡(jiǎn)單的話,建議你在iOS的WebView中編寫(xiě)一下alert,實(shí)現(xiàn):title 是提示,內(nèi)容是:alert view,確定按鈕的文字是:好的。你就知道WebView的限制在哪里了。
因此要完成JS在Web App開(kāi)發(fā)當(dāng)中的***實(shí)踐,肯定要學(xué)習(xí)優(yōu)秀的思想和實(shí)現(xiàn)方法了。在這篇文章里面,筆者們暫時(shí)先不去做這種深入的討論。而是先把例子拋給大家,也許會(huì)在下一次討論的時(shí)候,再詳細(xì)深入以下這兩個(gè)項(xiàng)目。
***個(gè)是斯坦福的iOS開(kāi)發(fā)公開(kāi)課中的例子,使用objective-c實(shí)現(xiàn),一個(gè)簡(jiǎn)單的卡牌游戲。這是經(jīng)典的mvc開(kāi)發(fā)了。項(xiàng)目地址如下:https://github.com/lbj96347/Stanford-W2013-CardGame,如果您正在使用Mac,那恭喜你,可以馬上編譯這個(gè)游戲進(jìn)行測(cè)試以及代碼瀏覽。
第二個(gè)是使用JavaScript編寫(xiě)的例子,實(shí)現(xiàn)同樣的需求,做一個(gè)簡(jiǎn)單的卡牌游戲。但是使用的是HTML+CSS+JS開(kāi)發(fā)。同樣學(xué)習(xí)了繼承以及mvc的思想。項(xiàng)目地址是:https://github.com/lbj96347/JSMatchismo ,再次恭喜你,不管使用什么電腦,都可以隨時(shí)瀏覽代碼以及運(yùn)行該游戲。
Hybrid App的新思想
這兩年多以來(lái),因?yàn)槭袌?chǎng)的不同,也出現(xiàn)了不一樣的需求,各個(gè)技術(shù)都有了新的發(fā)展。對(duì)于Hybrid App來(lái)說(shuō),其實(shí)都有了一些新的解決方案。為了解決問(wèn)題其實(shí)最終思想都會(huì)被還原成以下幾個(gè)點(diǎn)上:
- 根據(jù)需求,選擇工具;
- 用適當(dāng)?shù)墓ぞ咦鲞m當(dāng)?shù)氖虑?,有針?duì)性地解決問(wèn)題;
- 世界是平衡的,對(duì)于開(kāi)發(fā)者來(lái)說(shuō),做的有用功越多,用戶體驗(yàn)就越好,反之越差;
- 跨平臺(tái)是一個(gè)"幌子",什么都做得到不代表什么都做得好
這也是筆者體驗(yàn)最深的幾個(gè)點(diǎn)。而且你會(huì)發(fā)現(xiàn)Hybrid技術(shù)也基本在跟隨這幾個(gè)點(diǎn)來(lái)走。
根據(jù)需求,選擇工具
如果你使用過(guò)Jquery Mobile,你做過(guò)過(guò)場(chǎng)動(dòng)畫(huà)(就是從一個(gè)view去到另一個(gè)view),過(guò)場(chǎng)動(dòng)畫(huà)在iOS的navigationController中很常見(jiàn),而且很 簡(jiǎn)單,效果很好很流暢。在Jquery Mobile中使用ajax,css去實(shí)現(xiàn)了,核心代碼可能就幾十行??赡芨鷌OS里面的差不多(如果包含動(dòng)畫(huà)),但是實(shí)際出來(lái)的效果卻差強(qiáng)人意。會(huì)出現(xiàn) 類(lèi)似的問(wèn)題:頁(yè)面抖動(dòng),感覺(jué)不連貫,在部分的設(shè)備下運(yùn)行緩慢。如果你的應(yīng)用要求的體驗(yàn)并不是很高,例如一些新聞?wù)故绢?lèi)應(yīng)用,更強(qiáng)調(diào)排版。這里小小的體驗(yàn)差 距,就可以忽略了。(因?yàn)橛?guó)BBC就是這么干的),但是如果你的應(yīng)用非常強(qiáng)調(diào)體驗(yàn)細(xì)節(jié),這里的解決方案可能就不適合了?;蛟S你要做優(yōu)化,但是優(yōu)化的時(shí)間 可能足以夠你去學(xué)習(xí)更多的東西了。這樣的話,你是繼續(xù)選擇用一個(gè)不成熟的工具,還是選擇去學(xué)習(xí)一種新的語(yǔ)言呢?所以還是根據(jù)需求而定吧。
另外一個(gè)例子。曾經(jīng)有人跟筆者提及到,在使用HTML和CSS編寫(xiě)應(yīng)用界面時(shí)確實(shí)很爽,但是效率不咋的。那為什么不嘗試把應(yīng)用內(nèi)容直接搬到 Canvas里面呢?構(gòu)造一套足夠強(qiáng)大的工具,一套足夠彪悍的UI組件,把整個(gè)應(yīng)用運(yùn)行于Canvas中。這種想法是很好的,但是其實(shí)里面的短板頁(yè)就出現(xiàn) 了,Canvas的性能雖高,但是里面的元素組件多了你可以保證效果高?所有的東西都會(huì)依賴于JavaScript,這對(duì)于Javascript來(lái)說(shuō)要構(gòu) 造足夠強(qiáng)悍的面向?qū)ο蟮慕M件,也非簡(jiǎn)單之事,拋棄了CSS和HTML,意味著內(nèi)部的設(shè)計(jì)組件能夠高度定制,松耦合做得非常好。完全是實(shí)現(xiàn)了一套新的 xcode和ui庫(kù)啊。這就不是在解決一兩個(gè)問(wèn)題了。既然有這么一個(gè)工具,筆者為什么不選擇更好的,例如Xamarin。
用適當(dāng)?shù)墓ぞ咦鲞m當(dāng)?shù)氖虑?/h3>
做游戲的朋友估計(jì)就深有體會(huì)了。為了解決Canvas性能的問(wèn)題,越來(lái)越多的人和應(yīng)用廠商(尤其是瀏覽器廠商),提供一種解決方案就是希望將 Canvas API和系統(tǒng)底層的API打通。意味著你只需要編寫(xiě)Canvas代碼,實(shí)際做渲染的時(shí)候使用的是系統(tǒng)底層的東西,整體上提高了性能。例如Ejecta http://impactjs.com/ejecta 這個(gè)東西。
對(duì)于開(kāi)發(fā)人員來(lái)說(shuō)用Javascript編寫(xiě)游戲邏輯以及做各種控制都非常舒服,而且因?yàn)橛玫腁PI相同,放到PC上(放開(kāi)性能問(wèn)題),同樣可以運(yùn) 行。這就真的做到了跨平臺(tái),但是又不缺乏效率。讓筆者感觸最深的就是@大城小胖在做混合應(yīng)用(做游戲)時(shí)的做法,小胖的游戲架構(gòu)。JS負(fù)責(zé)邏輯,引擎。 JS Binding綁定原生OpenGL,讓原生的來(lái)做復(fù)雜的渲染處理。HTML CSS可以處理UI(比如一些Button)。這就是典型的:讓工具去做其擅長(zhǎng)的事情。
跨平臺(tái)是一個(gè)"幌子"
為什么這么說(shuō)?筆者不是一直希望大家能夠跨平臺(tái)么?是的。但是要真的認(rèn)清這個(gè)坎。從IE兼容,到目前多個(gè)瀏覽器的亂戰(zhàn),到iOS以及Android 設(shè)備Web上的兼容,這不就是一個(gè)歷史的例子嘛??缙脚_(tái)不是不好,只是在一個(gè)時(shí)代里,你能夠達(dá)到怎樣的效果,真的是很難估量的。就好比你出國(guó)旅游,如果兩 國(guó)關(guān)系非常好,而且很多慣例法律一致,對(duì)你來(lái)說(shuō)不會(huì)造成太多負(fù)擔(dān)。但是如果語(yǔ)言不一樣,生活習(xí)慣什么的都不同,你就很難適應(yīng)。同樣是人,你很難在不同的環(huán) 境下生存。真正的跨平臺(tái),就意味著大家求同。這絕對(duì)不是一兩天的事情,也非簡(jiǎn)單的事情。
那為什么還要跨平臺(tái)。業(yè)務(wù)需求嘛。在這里必須就要遵守根據(jù)需求選擇工具,用適當(dāng)?shù)墓ぞ咦鲞m當(dāng)?shù)氖虑?,根?jù)實(shí)際情況來(lái)作開(kāi)發(fā)。如果可以,筆者覺(jué)得很有 必要都了解一遍,這樣的話各種開(kāi)發(fā)的思想就會(huì)影響到你,你就能夠分辨到什么是好什么是壞,做更好的選擇。例如筆者剛剛說(shuō)到的過(guò)場(chǎng)動(dòng)畫(huà)的例子。其實(shí)完全可以 使用筆者說(shuō)的混合應(yīng)用中,方案三,去解決這個(gè)問(wèn)題。你無(wú)非就是希望用navigationController做一個(gè)漂亮的過(guò)場(chǎng)動(dòng)畫(huà)嘛,在iOS中幾句代 碼就實(shí)現(xiàn)了。
再說(shuō)一個(gè)例子吧,如果你正在做一個(gè)todo-list的應(yīng)用,其實(shí)無(wú)非就是簡(jiǎn)單存儲(chǔ)數(shù)據(jù)以及做一些相關(guān)界面渲染。在使用原生的控件的話,有大堆的代碼要寫(xiě),而且還要處理好內(nèi)存問(wèn)題。但是其實(shí)如果使用Web的方式實(shí)現(xiàn),比如backbone.js??傮w代碼可能100行左右。就把整個(gè)應(yīng)用實(shí)現(xiàn)了,包括本地存儲(chǔ)。你要做的事情就是把整個(gè)界面搭建得漂亮些??赡芫?個(gè)小時(shí)的工作。但是如果用原生開(kāi)發(fā),很難保證到一個(gè)小時(shí)內(nèi)完成,因?yàn)檎{(diào)試編譯都需要時(shí)間吧?況且還有界面呢。
所以要認(rèn)清跨平臺(tái)這個(gè)"幌子",并非所有的問(wèn)題都用同一個(gè)方法處理。筆者們要融匯貫通嘛!
總結(jié)和筆者的感受
對(duì)于做Web App的坑,其實(shí)挺多的。這里無(wú)法一一表達(dá)。但是相信實(shí)踐過(guò)就會(huì)知道如何更好地繞過(guò)這些坑(例如筆者說(shuō)的過(guò)場(chǎng)動(dòng)畫(huà)的例子)。那么對(duì)于開(kāi)發(fā)者來(lái)說(shuō)要有堅(jiān)強(qiáng)的 毅力,努力去實(shí)踐,滿足自己永遠(yuǎn)不能滿足的好奇心,因?yàn)樽罱K的經(jīng)驗(yàn)會(huì)給你帶來(lái)不一樣的感受,stay hungry。同時(shí)筆者們必須保持一顆學(xué)習(xí)的心,不斷地吸收有營(yíng)養(yǎng)的思想,學(xué)習(xí)新的知識(shí),不要太容易滿足,stay foolish。每一種語(yǔ)言都會(huì)有其中的思想,每一種工具都有自己解決問(wèn)題的方法論。多嘗試就能夠給自己帶來(lái)更優(yōu)秀的架構(gòu),更優(yōu)秀的應(yīng)用,提供給用戶更好 的體驗(yàn)。當(dāng)然,也會(huì)有更好的回報(bào)。