hybrid簡單瞭解

技術點總有它的來由。javascript

文章概要:css

  • 1.hybrid 基本概念
  • 2.前端和客戶端的交互
  • 3.前端和客戶端的交互實現
  • 4.前端交互實現關注點
  • 5.小結

 1.hybrid 基本概念

⑴.什麼是hybrid?html

hybrid即「混合」,前端和客戶端的混合開發模式,某些環節也可能涉及到 server 端。 hybrid 底層依賴於Native提供的容器(WebView),上層使用html&css&JS作業務開發。前端

⑵.webview是什麼?java

app中的一個組件,相似於小型瀏覽器內核。native提供的容器盒子,用於加載h5頁面。ios

圖中表示了兩種h5頁面資源運用的方式
   ①以靜態資源打包到app內的方式。
    前端將代碼提供給native,native客戶端拿到前端靜態頁面,以文件形式存儲在 app 中。這種模式,若是前端靜態頁面須要更新,客戶端就須要去server端下載靜態資源,即客戶端每次打開須要去線上檢查有無更新包有就下載壓縮包,解壓更新靜態資源。
 優勢:由於資源在本地,經過file 協議讀取,讀取速度很是快,且能夠作到斷網模式下頁面合理的展現。
  • 這樣就涉及到了一個server端靜態資源包管理系統。
  • 同時H5的資源是靜態的存儲在native本地,以file的方式讀取,那麼H5向遠端發起的請求就存在跨域,因此H5的請求須要通過native作一層代理轉發。
  • 靜態資源越多native包就越大(因此這種模式更適用於,產品功能穩定,體驗要求又高,且迭代頻繁的場景)。
   ②以線上url方式(更偏H5)
 將資源部署在線上,native打開一個新的webview請求線上資源展現(同在瀏覽器中輸入url,查看頁面過程一致)
 優勢:按需加載,用戶使用到的頁面纔會更新,發請求能夠不通過native作代理。
  • 不可避免請求線上資源,都須要時間,因此會出現瞬間白屏(弱網模式特別明顯)。
  • 斷網模式下沒有內容顯示。
  ③兩種模式資源加載
  本地讀取:
    
    線上讀取:
    
 

(3).hybrid存在的意義?git

能夠快速迭代開發更新。(無需app審覈,哈哈由於對手機的操做權限不高?,相對於app)github

hybrid開發效率高,低成本,跨平臺,ios和安卓共用一套h5代碼。(ios和安卓接口一致)web

hybrid從業務開發上講,沒有版本問題,有BUG能及時修復(相對於app)。chrome

 2.前端和客戶端的通信

native提供的容器盒子,用於加載h5頁面,那麼h5的頁面要怎麼跟native交互?

前端和客戶端的交互大概描述:

  • JS訪問客戶端的能力,傳遞參數和回調函數。
  • 客戶端經過回調函數返回內容。

前端的頁面跟native交互,是經過schema協議。(事實上Native能捕捉webview發出的一切請求,這個協議的意義在於能夠在瀏覽器中直接打開APP)

⑴.什麼是schema協議?

大概描述 :scheme是一種頁面內跳轉協議,經過定義本身的scheme協議,native 攔截這個請求,能夠很是方便跳轉app中的各個頁面。 

經過執行如下操做支持自定義URL方案:

  • 定義應用程序schema URL的格式。
  • 註冊應用程序schema URL方案,以便系統將適當的URL定向到應用程序。
  • 應用程序處理收到的網址URL。

一些URL Scheme 

https://www.zhihu.com/question/19907735

截取一端代碼,代碼來源:https://github.com/tcoulter/jockeyJS/blob/master/JockeyJS/JS/jockey.JS

// 這段代碼主要功能是前端經過一個特殊的協議給客戶端發消息,客戶端攔截請求而後處理
dispatchMessage: function(type, envelope) {
    // We send the message by navigating the browser to a special URL.
    // The iOS library will catch the navigation, prevent the UIWebView
    // from continuing, and use the data in the URL to execute code
    // within the iOS app.

var src = "jockey://" + type + "/" + envelope.id + "?" + encodeURIComponent(JSON.stringify(envelope)); var iframe = document.createElement("iframe"); iframe.setAttribute("src", src); document.documentElement.appendChild(iframe); iframe.parentNode.removeChild(iframe); iframe = null; }

⑵.具體H5與Native通訊,JS to native?

JS與Native通訊通常都是建立這類URL被Native捕獲處理。

.native到h5頁面,native to JS

native提供的容器盒子那麼native,能否調用它提供的webview中window對象的方法了?

native 能夠 調用以前跟前端約定好的掛載在window對象上面的方法。(具體實現了?)

                                                                          (圖片來源點擊)

/ Send an event to JavaScript, passing a payload.
// payload can be an NSDictionary or NSArray, or anything that is serializable to JSON.
// It can be nil.
[Jockey send:@"event-name" withPayload:payload toWebView:webView];

// If you want to send an event and also execute code within the iOS app when all
// JavaScript listeners have finished processing.
[Jockey send:@"event-name" withPayload:payload toWebView:webView perform:^{
  // Respond to callback.
}];

 

 3.前端和客戶端的交互實現

 前端與Native兩種交互形式:

① URL Schema(前端先定義對象,以及交互方法)

② 客戶端定義對象,注入全局變量(Android自己就支持相似的實現,因此此處討論ios的JavaScriptCore )

JavaScriptCore是一個C++實現的開源項目。使用Apple提供的JavaScriptCore框架,能夠在Objective-C或者基於C的程序中執行Javascript代碼,也能夠向JavaScript環境中插入一些自定義的對象。JavaScriptCore從iOS 7.0以後能夠直接使用,資料:https://developer.apple.com/documentation/javascriptcore。

⑴.URL Schema(前端先定義對象,以及交互方法)

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1">
    <title>Document</title>
</head>
<body>
    <button id="btn1">掃一掃</button>
    <script type="text/javascript">
        function send(type, payload,callback) {
            var envelope = {
                id: id,
                type: type,
                host: host,
                payload: payload
            };
            window.myapp.[envelop.id] = callback;
            var src = "myapp://"+envelope.id + "?" + encodeURIComponent(JSON.stringify(envelop));
            //告訴客戶端此時調用的函數, 函數執行完成後,告訴h5執行window.myapp.[envelop.id]這個函數。
       // host 加入使得客戶端更容易控制是否響應和處理(畢竟app內可能有需求內嵌第三方頁面)
var iframe = document.createElement("iframe"); iframe.setAttribute("src", src); document.documentElement.appendChild(iframe); iframe.parentNode.removeChild(iframe); iframe = null; } document.getElementById('btn1').addEventListener('click', function () { send("scan", {}, (payload) => { console.log("hi") }) }) </script> </body> </html>

 一般代碼實現會把send函數部分進行封裝,前端只須要實現與native約定的功能函數。

getPort: function() {
    window.send("getPort", {}, (payload) => {

    });
},
login: function(args = {}) {
    window.send("login", args, (payload) => {

    });
},

⑵.客戶端定義對象,注入全局變量(客戶端注入全局變量,供h5使用)

// 頁面調用了未聲明方法,事實上是Native注入給window對象的。(native在本地實現了js方法並注入h5)
// 在頁面加載完成前注入全局變量myapp,myapp下面的方法,即app提供的API方法 myapp.getPort(data, (payload)
=> { }); myapp.login(data, (payload) => { });

兩種方式的區別,由客戶端仍是由h5預先定義對象,以及交互方法 。

 4.前端交互實現關注點

 代碼來源:https://github.com/tcoulter/jockeyJS/blob/master/JockeyJS/JS/jockey.JS(如下代碼例子,以URL Schema方式爲基礎)

⑴.導航欄的設置

導航欄一般是native實現,有回按鈕退防止頁面假死,即頁面卡死能夠回退。

同時native須要提供API供h5進行簡單的定製(好比有的須要關閉按鈕,分享按鈕,收藏按鈕等)

setBarBack() {
    Jockey.send("setBarBack", {
        "bar": {
            "position": "left",
            "cliekEvent": "onBack",
        }
    }); 
    // 取消監聽onBack事件
    Jockey.off('onBack');
    // 監聽onBack事件
    Jockey.on('onBack', () => {
        history.back()
    });
},

⑵.跳轉是Hybrid必用API之一,對前端來講有如下跳轉:

① H5跳轉Native界面

② H5新開Webview跳轉H5頁面。

用native的方法來跳轉,通常是爲了作頁面的動畫切換。

 如圖咱們一般只會使用到導航欄下面部分,但咱們關注頁面的導航欄,H5端能夠註冊事件監聽native的導航欄的事件(非必須)

⑶.獲取基本信息

在具有用戶體系的模式下,H5頁面能從native拿到基本的登陸信息,Native自己就保存了用戶信息,提供接口給h5使用。

function getInfo() {
    return new Promise((resolve, reject) => {
        Jockey.send("getInfo", {}, (payload) => {
        
        });
    });
},

⑷.調用native原生具有的功能

相機,手機頁面橫屏顯示或者豎屏顯示等。

⑸.關於調試

Android:輸入chrome://inspect/#devices便可(前提native打開了調試模式),固然Android也可使用模擬器,但與Android的真機表現過於不同,仍是建議使用真機測試。

iOS:需一臺Mac機,而後打開safari,在偏好設置中將開發模式打開,而後點擊打開safari瀏覽器,查看菜單欄開發菜單(前提native打開了調試模式)...

 

 5.小結

文章只是一個對hybrid的簡單瞭解,文中例子比較粗糙,理解不許確之處,還請教正。對於有興趣深刻了解Hybrid技術的設計與實現前端部分細節的能夠看看參考資料~~

 

 

參考資料:

http://www.cnblogs.com/yexiaochai/p/4921635.html

http://www.cnblogs.com/yexiaochai/p/5524783.html

http://www.cnblogs.com/yexiaochai/p/5813248.html

相關文章
相關標籤/搜索