基於HTML開發手機應用的新模式
1 引子
不知什麼時候開始,iOS和Android火了,手機應用程式設計師的薪水突地坐上了神舟5號,一夜之間一升再升,直接擺脫了地球引力,飛出大氣層。然而,不是每個公司都有這樣的實力和魄力,養得起程式設計師中的高富帥。
屌絲老闆想做手機應用充高富帥,但養不起高富帥程式設計師;屌絲程式設計師想躋身高富帥,但不會做手機應用。於是,物競天擇的屌絲群中,冒出了一撮聰明人,他們認為用瀏覽器也可以做手機應用。事實證明,這群人的想法行得通,儘管頭上還頂著“非主流”三個字。
做手機開發的童靴們,最不可忍受的應該是模擬器了;每次修改和除錯程式,模擬器都需要對應用進行解除安裝和安裝,並同步除錯程序,最噁心的是偶爾還要重啟模擬器,這真真是一個磨礪心性的強大武器(高富帥也有難受的時候?)。
屌絲們的夢想是基於HTML的,可以省去很多工作,比如程式碼的編譯,打包,重新發布等工作。但不可避免,介面的調整和功能的除錯,大部分時候還是會迴歸到模擬器中來(事實上,直接通過USB連手機除錯,比模擬器快N倍,不過這樣一來對屌絲們的裝備就有所要求了)。
基於HTML開發手機應用,不論是網頁應用,還是基於各類框架(PhongGap、AppCan、Rexsee之流)的本地應用,其事實上都有一個重要的基礎媒介:瀏覽器(這大概也是WebKit名聲大噪的原因之一)。
到這裡,童靴們大概還沒明白我要說什麼?
其實我想說:咱們就直接用Chrome充當模擬器吧。
我們知道(iOS和Android)手機上的瀏覽器都是基於WebKit核心,唯一的區別就是WebKit的版本不一樣。當然,這會導致一個比較嚴重的問題,就是WebKit不同的版本,對HTML和CSS標準的支援有些差異。
恩,這也讓我們學會一個鐵則:儘量採用相容性比較好的HTML標籤和CSS屬性!
既然如此,那麼用Chrome做模擬器,就顯得理所當然了。儘管手機和PC的解析度不一樣,在一些細節的展現和處理上會有些微差異;但勝在PC的速度夠快夠方便,不管是除錯程式邏輯,還是介面流程,都是流暢自如暢快淋漓。
3.1 js的滲透程度
很多童靴害怕接管太多的事件,希望最大程度的藉助瀏覽器及各種框架(jqMobi、jQueryMobile之流)本身的功能,並且潛意識裡覺得(更多的是期望)二者已經為我們提供了足夠好的封裝。
然而事實並非如此,手機不同於PC,使用者喜歡用更少的流量和更快的速度,瀏覽更多的內容。如果僅僅是採用瀏覽器和框架提供的功能,至少我們就無法使用快取(說localStorage更貼切點)。所以我們必須認真考慮js程式碼的滲透程度,也可以理解為程式中有多少連結是由js來控制的?這沒有標準答案。但好在可以給童靴們提供一條建議:但凡頁面內容是動態請求而來的,請接管這個連結。
上面提到用Chrome充當模擬器,事實上程式碼在Chrome和手機瀏覽器上執行,還是會有一定的差異,特別是我們採用了框架的情況下(如:PhoneGap)。
解決差異的辦法,可以沿用古老的門面模式來實現。
假設我們需要在頁面上輸出裝置名稱(我們知道,在Chrome中是沒有device物件的):
var Device = {
name: function() {
if(isMobile()){
returndevice.name;
}else {
return"chrome";
}
}
};
這樣,我們在後續的js程式碼中,都可以通過Device.name()來獲取裝置名稱,即使我們是在Chrome中執行,也能得到一個裝置名稱,從而獲得程式碼的一致性。
到這裡,大概有童靴已經能預見我們要說的彼岸之路是怎樣的了。
是的,我們可以這樣:
² 設計一個全域性物件,通過門面模式,對外提供應用所需的全部功能呼叫。
² 接管所有動態內容的頁面連結,並用js實現頁面內容的填充。
² 儘量採用有良好相容性的HTML標籤和CSS屬性。
² 採用Chrome充當模擬器。
有童靴要講,我不這樣做,同樣可以通向彼岸的說。
沒錯,這不是唯一的路,但這樣做,絕對可以讓你的開發速度提升一截;最關鍵的是你的程式碼更優雅,也更穩定。
4 構築模式
這也有模式嗎?這個可以有。
我們稍微梳理一下,就可以知道在HTML應用中需要用到的功能有:
² 應用名稱及版本。
² 遠端伺服器地址及各請求路徑。
² 快取(可分為localStorage和cache)及資料庫。
² 其他公用功能,如HTTP請求等。
² 應用中需要用到的功能。
如果基於這幾點出發,我就可以設計一個全域性物件,囊括上述所有功能呼叫和屬性。那麼,在整個應用的生命週期裡,我們的其他js程式碼就可以簡單的通過這個物件來獲取所需資料,僅僅只關注與業務邏輯相關的UI的控制即可。換句話說,我們把底層功能都封裝在這個全域性物件上,而UI和流程的控制,則交給其他的js程式碼(顯而易見的,js程式碼也被分層了,是不是?)。
恩,用範例程式碼說話,就是這樣:
var Html5App = {
appName: 'Hello',
appVersion: '1.0',
baseUrl: 'http://xxx/mobile/',
servPath: {
LOGIN: 'login.do',
LOGOUT: 'logout.do'
},
ensureUrl: function(url) {
...
},
storage: {
/*
* 獲取已儲存物件
*/
get: function(key) {
...
},
/*
* 儲存物件到本地
*/
set: function(key, val) {
...
},
/*
* 清除所有已儲存的資料
*/
clear: function() {
...
}
},
cache: {
/*
* 獲取已快取的物件
*/
get: function(key) {
...
},
/*
* 儲存物件到快取
*/
set: function(key, val) {
...
},
/*
* 清除所有快取資料
*/
clear: function() {
...
}
},
user: {
login: function(user, pwd) {
...
},
logout: function() {
...
}
}
...
};
5 後記
英雄出身草莽,屌絲程式設計師中同樣不乏聰明人,應該很快會看到基於這種模式而延展出來的框架,我們拭目以待……