基於webview的Hybrid app和React Native及html5


基於webview的Hybrid app和React Native及html5

React Native 結合了 Web 應用和 Native 應用的優勢,可以使用 JavaScript 來開發 iOS 和 Android 原生應用。
在 JavaScript 中用 React 抽象操作系統原生的 UI 組件,代替 DOM 元素來渲染等。
React Native 使你能夠使用基於 JavaScript 和 React 一致的開發體驗在本地平台上構建世界一流的應用程序體驗。
React Native 把重點放在所有開發人員關心的平台的開發效率上——開發者只需學習一種語言就能輕易為任何平台高效地編寫代碼。
Facebook 在多個應用程序產品中使用了 React Native,並將繼續為 React Native 投資。

react native - react native 中文網
http://reactnative.cn/

如何評價 React Native? - Android 開發 - 知乎
http://www.zhihu.com/question/27852694
facebook開源的React Native 聽說這個比基於webview的Hybrid app要好很多

React Native的優勢和劣勢:
優勢相對Hybird app或者Webapp:
1. 不用Webview,徹底擺脫了Webview讓人不爽的交互和性能問題
2. 有較強的擴展性,這是因為Native端提供的是基本控件,JS可以自由組合使用
3. 可以直接使用Native原生的動畫(在FB Group這個app里面,面板滑出帶一點果凍彈動,面板基於某個點展開這種動畫隨處可見,這種動畫用Native code來做小菜一碟,但是用Web來做就難上加難)。
優勢相對於Native app:
1. 可以通過更新遠端JS,直接更新app,不過這快成為各家大型Native app的標配了.
劣勢:
1. 擴展性仍然遠遠不如web,也遠遠不如直接寫Native code
2. 從Native到Web,要做很多概念轉換,勢必造成雙方都要妥協。
比如web要用一套CSS的閹割版,Native通過css-layout拿到最終樣式再轉換成native原生的表達方式(比如iOS的Constraint\origin\Center等屬性),再比如動畫。
另外,若Android和iOS都要做相同的封裝,概念轉換就更復雜了。

UPDATE list:
2015.9.21 React Native Android 9.15 提前發布,補充AppStore審核政策變化。
2015.5.23 Slide:上海前端技術峰會,http://yunpan.taobao.com/s/GeUkc7lAfI
2015.4.24 Slide:QCon北京2015,“http://www.stuq.org/ppt/show/95/5c28db3ecf661208387127be8878aed3#/1”
2015.4.17 天貓前端@橫天同學發表的react-native 之布局篇對css-layout的布局能力做了一些實驗,給出了一些有價值的結論,如:react 寬度基於pt為單位;flex能實現網格系統需求,且網格能夠各種嵌套無bug;padding 設置在Text元素上所有padding變成了marginBottom...
2015.4.11 風險,iOS6 javascriptCore.framework 為私有,可以通過JavaScriptCore-iOS · GitHub這個庫代替。

========================================
Android Hybrid App四大坑

首先解釋下題目,Hybrid App,混合應用,代表平台PhoneGap,一般指使用原生包裝Web頁面開發的應用。
與原生應用相比,主要用戶界面和業務邏輯都是用Web技術也就是HTML+CSS+Javascript實現的;與Web應用相比,Web部分打包在應用內部,使用時不需要網絡。
順便說一句,很多解決方案其實不算Hybrid,比如Adobe AIR、Titanium、Mono,這些都是使用某一特定技術開發跨平台應用的工具,最終產品都是編譯成原生來跑的。

我們沒有選擇PhoenGap為技術基礎(我對此並不滿意,我認為以PhoneGap為基礎可以少走一些彎路,少花一些精力,還能產出很多有價值的副產品),而是自行開發原生框架,主要目標平台是Android——嗯,就是那個從系統版本到模塊組合都巨分散的Android,
可以這么說,坎坷從立項的那一刻起就已經注定了……接下來,便請聽我一一講述:Android Hybrid App四大坑。(此文主要針對Android 4.3及之前的webview,部分瀏覽器比如Chrome已經改善了具體實現,所以Web App其實環境不錯。)

前端代碼開源就好,https://github.com/Dianjoy/gamepop,要跑起來需要修改config.js,把if (debug) {}的內容刪掉。

缺少標准flexbox
Flexbox是CSS3里面一項非常重要的改進,大大改善了布局工作。可惜從草案到終案時間跨度太長,於是市面上絕大部分設備只支持display:-webkit-box。這給上圖中圖標區域的布局帶來了難處,最終只能混合使用兩種布局,display:inline-block和display:flex。
需要注意,inline-block元素之間,如果在代碼中有空格換行符的話,渲染時會有約0.25em~0.5em大小的間隙,所以想一行4列每列width:25%的話會放不下導致折行。
開始我在其父元素中設置font:0/0 a,大部分手機都OK,中興ZTE795就不行,擦,上次也是它……后來我索性把所有空格和換行符都干掉,終於OK了。

這段代碼演示inline-block布局時父元素字體對子元素之間間歇的影響。

<iframe src="http://jsfiddle.net/meathill/9Uk5Y/embedded/result,html,css,js/presentation/" height="200" width="100%" allowfullscreen="allowfullscreen" frameborder="0"></iframe>
所以,對於多行多列的grid布局,我們要謹記:

對父元素使用display:flex; flex-direction: row; flex-wrap: wrap;在現代瀏覽器和Android4.4以上的系統中,可以取得完美表現。
使用display:inline-block; box-sizing: border-box; vertical-align: top;,並且在代碼中移除塊與塊之間的空白字符,避免換行,保留合適的邊距。
遺憾的是,低版本的webview中,高度不會自適應,除非使用js進行計算,不然還是盡量避免在元素下方畫線的舉動。

tap vs click
(這個問題簡直令人發指。)我們知道,很多瀏覽器默認行為都依賴click事件觸發,比如超鏈接、input[type=radio]的選中,等等。在4.4之前的webview中,click比真實操作延遲約300ms觸發,會帶給用戶明顯的延滯感。為了提升用戶體驗,我們多數使用tap事件部分替代click事件,以便及時響應用戶操作。可選方案很多,Hammer.js、Fastclick,甚至Zepto都有封裝。

於是新的問題出現了。比如我們用<a>實現了一個刪除按鈕,tap時,刪除當前元素,並且將按鈕重置為下載按鈕,href為下載的url。用PC開發時一切正常,但到真機測試就會發現,因為tap是即時的,新按鈕立刻替換了舊按鈕,300ms后,click事件在新按鈕上觸發了,結果又開始下載……
再比如,圖層中有個后退按鈕,點擊后,圖層移除,露出下面覆蓋的部分,如果在tap的位置上剛好有一枚鏈接,此時就會觸發click,頁面跳轉……以及,上次總結說的下載鏈接不觸發click,問題也一樣,只不過翻過來,click該觸發的時候,被圖層擋住了,所以沒有觸發。


解決方案基本圍繞“如何熬過300ms”,和“甄別事件對象”來設計。

還是上面兩個場景,第一個,按下之后,setTimeout 400ms(以防萬一)后再替換按鈕;第二個,給圖層加一個消失的動畫,持續400ms,保證click觸發時圖層還在。可能大家有疑問,為何不干脆禁掉click事件,前面說了,很多瀏覽器默認行為依賴click事件,禁掉之后又會引發別的問題。

另一個解決方案是甄別事件對象,在用戶touchstart的時候,記下event.target,等到click觸發時,對比,如果不一致則認為是抽風,event.preventDefault()。我更推薦這種做法,畢竟400ms也不算短。不過要注意,<label>在響應click時,會自動觸發它for的元素的click,所以要用新增的control屬性進行二次對比,以免誤傷。

position:relative;竟然搶事件
這個問題解決起來容易,排查時沒少花時間。表現為,一個按鈕,就在那里,但怎么點都沒用。后來只好追蹤全局事件,發現事件的對象並非按鈕,而是按鈕下面被遮蓋的層。
很奇怪,我知道translateZ可能導致這個問題,不過現在完全沒用到;而且下面的圖層實際並沒有那么長(參照上圖中,內容列表和下面的三個按鈕,就是那里),列表的底部是bottom:60px,剛好應該把<footer>的三個按鈕空出來。

然后我開始懷疑position:relative;,因為只有這個東西會影響布局。把它點掉后,按鈕果然可以點了,於是我給<footer>也加上了position:relative;問題就這樣解決了。我覺得這肯定又是個Android Webview的Bug,因為我並沒有給下面層里的元素設置z-index,只有position:relative。總之,如果按鈕點擊沒反應,盡早看看事件對象是哪個,說不定被哪個層搶走了。

各種待實現的API
caniuse.com是個神器,我在使用某個API或者CSS屬性時不太有把握的話,都會去查一下。然而,誰又知道Android Webview默認很多API都沒開呢?大到localStorage,小到alert、confirm,都需要主動開放,不然就沒法用。測試的時候又很難查,原生的環境多不在我這兒,配也不太容易,大家的習慣都不一致,只能等對方反饋過來錯誤信息,我到代碼里查,但常常死活看不出來哪兒有問題。

后來認清現實就好辦,Android Webview其實是個半殘廢,有不明白的問題,多半是API實現不全導致的。最簡單的辦法是用modernizr之類的工具進行特性檢測,或者在Weinre、Adobe Inspect CC里直接敲API。總之,別懷疑自己,基本都是Android Webview的問題。

這也是我為什么希望以PhoneGap為基礎的原因:PhoneGap已經按照規范實現了大部分API。插件庫也很豐富,比如GA——說到這個,我們想實現一個簡單的統計,因為老板嫌GA太大,所以干脆使用同樣的接口,只請求一下我們的日志服務器,留下條日志就好,結果我們驚訝地發現:Android里原生給Webview環境增加API,方法的參數不能多也不能少,不然就報錯,真奇葩——可以省下很多時間。
產出的結果,還可以分享到社區一部分,對於我們公司,也能增加了不少開發者資源。

總結
早先別人鄙視Hybrid App的時候我也各種不服,心說“你們丫懂毛啊就指手畫腳的說不行”;現在經歷了各種大坑小坑連環坑之后,我的想法已經變成了“你們丫懂毛啊不就是一不小心蒙對了么”。

Hybrid App開發會遭遇比原生和Web App更多的坎坷,這我有心理准備;如此多的坑無形中也在提升我的個人價值,我對此甚至隱隱有些高興。
不過我還是希望這段混亂之治盡快過去,Android平台不要再分裂了,高版本系統盡快普及,所有前端開發的日子都會好過許多。

現在,如果可能的話,盡量以PhoneGap為基礎進行開發,能省很多時間和精力。對於前端人來說,更是能把測試環境搬到本地,實在是非常大的幫助。

Android 4.4時再次分裂,之后使用blink作為webview的基礎;之前則是webkit,前者無論CSS還是API都有更佳表現,Nexus 5基本沒怎么改就都測試通過了。
2014年03月16日發布

===========================================

web就是天生的多平台 web+ios+android+wp+。。。
web用戶體驗不好,盡量優化
關鍵是想怎么改就怎么改,隨時上線,不用審核
只有用到第三方的東西(登錄、支付、推送。。。)才要用到原生的
而這些,j2objc就沒轍了,還是得重新開發
看來html5的web開發是大趨勢

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM