1. 程式人生 > >基於HTML開發手機應用的新模式

基於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     後記

英雄出身草莽,屌絲程式設計師中同樣不乏聰明人,應該很快會看到基於這種模式而延展出來的框架,我們拭目以待……