hybrid方案背景javascript
大部分業務都是在不停改變的,咱們但願native不發佈新版本就可讓線上用戶使用新功能。咱們要實現這樣的方式,採用h5來實現就能夠知足這一要求,準確說是native裏提供一個裝載h5的webview容器。單獨使用h5完成整個應用和單獨使用native來實如今體驗上相差太大,因此考慮使用混合開發的方式。強調體驗的地方使用native,其餘地方使用h5,這樣一來體驗方面能夠大幅提高。java
h5與native如何交互git
h5和native的交互一般是三種:github
一、native提供方法,js調用native的方法。web
二、native在本地注入js方法而且調用。跨域
三、webview攔截請求,js發起自定義協議,native在請求裏面攔截處理。緩存
下面對分別進行一些介紹。網絡
方案一app
一、native注入對象(有一系列供js使用的方法)以及提供給js調用的名稱。ide
webView.addJavascriptInterface(new HybridJsInterface(),"HybridJSInterface");
二、native提供能夠供js調用的方法。
public class HybridJsInterface {
@JavascriptInterface
final public void hello(String text) {
Log.i("method hello","text="+text);
} }
三、js調用native的方法。
function hybrid(){
window.HybridJSInterface.hello("hello hybrid");
}
方案二
一、native注入js方法。(也能夠是h5直接提供的方法)
// function helloJs(){
// alert("hello js");
// }
String script = "function helloJs(){ alert('hello js');}";
//script是js方法對應的字符串
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
mWebContent.evaluateJavascript(script, null);
} else {
mWebContent.loadUrl("javascript:" + script);
}
}
二、native調用注入的js方法
String handle = "helloJs()"; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { mWebContent.evaluateJavascript(handle, null); } else { mWebContent.loadUrl("javascript:" + handle); }
注入和調用能夠合併在一塊兒,我的建議注入方法和調用方法分別執行。
方案三
一、native攔截h5發過來的請求協議(自定義協議)。
webview位置攔截的WebViewClient對象。
webView.setWebViewClient(new HybridWebViewClient());
HybridWebViewClient重寫shouldOverrideUrlLoading方法
public boolean shouldOverrideUrlLoading(WebView view, String url) { Uri parse = Uri.parse(url); String path = parse.getPath(); switch (path) { //TODO } }
二、js那邊發起請求協議。
方案分析
這三種方案單獨使用都比較有侷限性。
方案一的思路是native提早給h5實現好h5須要使用的方法,方法調用徹底由h5控制,缺陷是h5調用的功能實現都由native實現,當h5頁面中須要新功能的時候須要修改native才能支持。
方案二的思路是js提早給native提供方法,方法調用徹底由native控制,缺陷是當js提供了新的方法那麼須要修改native主動調用才能使用新功能。
方案三的思路是native攔截h5發過了的請求進行分發控制,js須要使用的功能是native已經提早準備好的,使用不一樣的url進行分發來使用,缺陷是h5使用新的功能那麼須要修改native提供新功能。
單獨使用這三種方案的共同缺點就是js和native都是一個單向的調用,相互太過依賴。要是三種方案都用上是否是能夠解決問題呢,其實根本問題不在這裏,而在於這些方案都沒有辦法動態擴展,也就是說native一旦完成以後那麼單純靠js是很難完成功能擴展的。咱們須要一種能夠適應必定程度動態擴展的方案,那就讓h5做爲項目主導,native提供服務。
hybrid設計
整體設計思路是h5控制整個業務流程以及交互流程。h5那邊負責發命令而且回調,native負責響應命令。我是採用方案三來實現,客戶端須要作的就是預先處理好這些命令(url)。既然是響應命令那麼首先就須要把和業務無關的命令給整理出來,比較通用的包括下面內容(不必定全):
一、header控制。
heade的樣式能夠參考新聞類app的詳情頁(這裏不截圖),包括內容:左邊按鈕(多個),右邊按鈕(多個),主標題,副標題。
須要作的控制是左、右按鈕是否顯示、顯示的文本及圖標以及點擊按鈕的回調,主、副標題是否顯示及顯示內容。
二、頁面刷新。
頁面刷新用於內容改變以後h5主動通知native進行刷新。
三、頁面跳轉。
頁面跳轉分紅兩種一種是頁面跳轉到一個新的native頁面,另外一種是在webview內部作跳轉。native的跳轉包括內容:跳轉動畫、跳轉目標頁、目標頁須要的參數。
四、loadingview/progressbar。
一般狀況建議直接使用h5的進度顯示。loadingview的控制包括:loadingview是否顯示,loadingview的顯示樣式(一般只有一種樣式)。
五、傳感器數據。
傳感器這部分不必定每一個應用都須要。好比某些h5頁面須要作活動,那麼裏面可能會用的搖一搖這樣的功能。傳感器的控制包括:地理位置、方向、震動、運動量。
六、h5離線包更新。
離線包的更新對於h5來講是一條更新命令。不過在native實現上面須要包括:離線包更新檢查(版本比較)、離線包下載、離線包解壓保存。
七、離線包開關。
是否使用離線數據。native須要作的是開啓離線包命令以後須要把請求的url映射到本地文件緩存。
八、數據請求。
數據請求是指h5須要請求數據不經過直接網絡訪問,而是經過native本身的網絡服務獲取數據,尤爲是在跨域的狀況下很方便。
讀者能夠根據本身的須要實現這些功能,我這邊已經實現了,可是由於時間少尚未來得及整理代碼,在後期會放到github上。有任何問題歡迎討論,留下qq羣19676167七、311536202。