Flutter和H5之間橋接,互相調(diào)用

1. flutter中使用WebView

    WebView(
      initialUrl:
          "http://100.84.184.27:80/FlutterH5Demo/dist/index.html",
    ),

純展示的頁面,上面的配置就可以,但是要想實(shí)現(xiàn)Flutter和H5的雙向數(shù)據(jù)交流,就需要像原生和H5之間交換數(shù)據(jù)那樣,搭建一個(gè)Bridge。
flutter提供了非常方便的Api,JavascriptChannels,配置如下:

    WebView(
      initialUrl:
          "http://100.84.184.27:80/FlutterH5Demo/dist/index.html",
      javascriptMode: JavascriptMode.unrestricted,
      onWebViewCreated: (controller) {
        webViewController = controller;
      },
      onPageFinished: (url) {},
      javascriptChannels: <JavascriptChannel>[
        JavascriptChannel(
          name: "FlutterBridge",
          onMessageReceived: (JavascriptMessage message) {
            print("js 發(fā)來消息 ${message.message}");
          },
        ),
      ].toSet(),
    ),

JavascriptMode.unrestricted即不限制使用JavaScript,必須開啟,不然channels無法使用,在javascriptChannels下可以配置一個(gè)集合,自定義需要的Channel,也即交換數(shù)據(jù)通道,這個(gè)通道用來接收H5傳來的數(shù)據(jù)。

JavascriptChannel由一個(gè)name和一個(gè)回調(diào)函數(shù)組成,name即協(xié)定好的方法Api,H5那邊會用到,這個(gè)name非常關(guān)鍵。實(shí)際開發(fā)中不需要定義多個(gè)name,一個(gè)通用的Api就可以,可以擴(kuò)展傳遞的數(shù)據(jù)。

2. H5調(diào)用flutter中的方法(即H5傳遞數(shù)據(jù)給Flutter)

先看H5中的代碼:

    <body>
    
    <p id="pid">Js的content</p>
    
    <script>
        window.android2Js = function (data) {
            document.getElementById("pid").innerText = "flutter 發(fā)來消息" + data;
        };
    
        document.getElementById("pid").addEventListener("click", function () {
            FlutterBridge.postMessage("來自JS的數(shù)據(jù)");
        });
    </script>
    </body>

p展示H5內(nèi)容,script中定義了一個(gè)window的方法android2Js,用于從Flutter中接收數(shù)據(jù),p標(biāo)簽的點(diǎn)擊事件觸發(fā)向Flutter傳遞數(shù)據(jù)。
在Flutter中定義的name,這個(gè)時(shí)候就用上了,F(xiàn)lutter會在webview中注入js方法postMessage,直接調(diào)用Api.postMessage,參數(shù)只接收一個(gè)String,就可以向Flutter發(fā)送數(shù)據(jù),F(xiàn)lutter的回調(diào)函數(shù)就可以接收到這個(gè)數(shù)據(jù)String。

3. Flutter調(diào)用H5中的方法(即Flutter傳遞數(shù)據(jù)給H5)

    GestureDetector(
      onTap: () {
        webViewController.evaluateJavascript(
            "android2Js('來自flutter的消息');");
      },
      child: Text(
        title,
        style: TextStyle(
          color: COLOR_333333,
          fontSize: 16,
          fontWeight: FontWeight.bold,
        ),
      ),
    ),

和原生中調(diào)用H5的方法類似,直接獲取webview的控制器,執(zhí)行js代碼,android2Js,傳遞參數(shù)類型String。

4. 一個(gè)JavascriptChannel,擴(kuò)展傳遞的數(shù)據(jù)

以上就完成了數(shù)據(jù)的交換,但是存在一個(gè)問題,如果兩個(gè)按鈕都調(diào)用同一個(gè)方法,無法判斷執(zhí)行回調(diào)的先后,導(dǎo)致數(shù)據(jù)錯(cuò)亂,所以需要給每一次調(diào)起分配一個(gè)id,簡單點(diǎn)時(shí)間戳就可以。

    {
        "pluginName": "",
        "data": {
            
        },
        "callbackId": Date.now(),
    }

調(diào)用方和執(zhí)行方都需要嚴(yán)格保持這樣的數(shù)據(jù)類型,【pluginName指定調(diào)用的插件類型,data指定業(yè)務(wù)參數(shù),callbackId唯一標(biāo)識一次調(diào)用】,才能保證方法調(diào)用不會混亂。

調(diào)用方需要維持一個(gè)callbackId和回調(diào)函數(shù)的映射表,執(zhí)行方在拿到callbackId的時(shí)候,執(zhí)行完成需要將這個(gè)callbackId傳回調(diào)用方,調(diào)用方收到消息,需要從映射表中取出回調(diào)函數(shù),執(zhí)行回調(diào),完成一次完整調(diào)用。

舉例說明:

    {
        "pluginName": "addBroadcast",
        "data": {
            "param1": 100,
            "param2": 200,
        },
        "callbackId": 1630329836113,
    }
    
    {
        "pluginName": "addBroadcast",
        "data": {
            "param1": 100,
            "param2": 200,
        },
        "callbackId": 1630329836114,
    }

映射表:
1630329836113 -> 回調(diào)函數(shù)1
1630329836114 -> 回調(diào)函數(shù)2

    {
        "pluginName": "addBroadcast",
        "data": {
            "param1": 100,
            "param2": 200,
        },
        "callbackId": 1630329836113,
    }
    
    {
        "pluginName": "addBroadcast",
        "data": {
            "param1": 100,
            "param2": 200,
        },
        "callbackId": 1630329836114,
    }
    {
        "pluginName": "addPlugin",
        "data": {
            "result": 300,
        },
        "callbackId": 1630329836113,
    }
    
    {
        "pluginName": "addPlugin",
        "data": {
            "result": 300,
        },
        "callbackId": 1630329836114,
    }
    {
        "pluginName": "addPlugin",
        "data": {
            "result": 300,
        },
        "callbackId": 1630329836113,
    }
    
    {
        "pluginName": "addPlugin",
        "data": {
            "result": 300,
        },
        "callbackId": 1630329836114,
    }

1630329836113查找映射表得到回調(diào)函數(shù)1,執(zhí)行回調(diào)方法;
1630329836114查找映射表得到回調(diào)函數(shù)2,執(zhí)行回調(diào)方法。
至此,flutter和H5的互相回調(diào)結(jié)束。【方便理解,flutter和H5的pluginName,一方叫廣播Broadcast,一方叫插件Plugin,和現(xiàn)有業(yè)務(wù)融合】

1630330541(1).jpg
img.png
img_1.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容