美文网首页Flutter圈子Flutter
Flutter使用JsBridge与WebView交互

Flutter使用JsBridge与WebView交互

作者: 小天枢丶 | 来源:发表于2020-04-16 10:23 被阅读0次

    近期把原先的navite app用flutter重写,原先app里面有大量通过JsBridge与web交互的逻辑,换到flutter这边之后发现没用现成可用的第三方库,然后自己写了一个bridge_webview_flutter

    第三方依赖

    在原先的webview里面加上相关的逻辑和依赖

    Android使用的是JsBridge

    ...
    rootProject.allprojects {
        repositories {
            google()
            jcenter()
            maven { url 'https://jitpack.io' }
        }
    }
    ...
    dependencies {
        implementation 'androidx.annotation:annotation:1.0.0'
        implementation 'androidx.webkit:webkit:1.0.0'
        compile 'com.github.lzyzsd:jsbridge:1.0.4'
    }
    ...
    

    iOS使用的是WebViewJavascriptBridge

    ...
    s.dependency 'Flutter'
    s.dependency 'WebViewJavascriptBridge'
    ...
    

    Navite与Flutter交互

    通过MethodChannel进行交互

    @override
    Future<void> callHandler(String name, {dynamic data, BridgeCallBack onCallBack}) {
        if (onCallBack != null) {
          _bridgeCallBackMap[name] = onCallBack;
        }
        return _channel.invokeMethod("callHandler", {"name": name, "data": data});
     }
    
    @override
    Future<void> registerHandler(String name, {dynamic response, BridgeCallBack onCallBack}) {
        if (onCallBack != null) {
          _bridgeCallBackMap[name] = onCallBack;
        }
        return _channel.invokeMethod("registerHandler", {"name": name, "response": response});
    }
    

    使用一个map来存储需要用到的回调函数

    iOS
    - (void)registerHandler:(FlutterMethodCall *)call {
       NSString *name = [call arguments][@"name"];
       id response = [call arguments][@"response"];
       if (name) {
            __weak typeof(self) weakSelf = self;
            [_bridge registerHandler:name handler:^(id data, WVJBResponseCallback responseCallback) {
                NSDictionary *callback = @{
                                @"name": name,
                                @"data": data
                            };
                __strong typeof(weakSelf) strongSelf = weakSelf;
                [strongSelf->_channel invokeMethod:@"bridgeCallBack" arguments:[self dictionaryToJsonString:callback]];
                if (response) {
                    if ([response isKindOfClass:[NSDictionary class]]) {
                        responseCallback([self dictionaryToJsonString:response]);
                    } else {
                        responseCallback(response);
                    }
                }
            }];
       }
    }
    
    - (void)callHandler:(FlutterMethodCall *)call {
        NSString *name = [call arguments][@"name"];
        id data = [call arguments][@"data"];
        if (name) {
            __weak typeof(self) weakSelf = self;
            [_bridge callHandler:name data:data responseCallback:^(id responseData) {
                NSDictionary *callback = @{
                                @"name": name,
                                @"data": responseData
                            };
                __strong typeof(weakSelf) strongSelf = weakSelf;
                [strongSelf->_channel invokeMethod:@"bridgeCallBack" arguments:[self dictionaryToJsonString:callback]];
            }];
        }
    }
    

    省略了一些配置代码,可以参考官方文档

    Android

    Android这边需要把原先的InputAwareWebView继承BridgeWebView
    然后再把原先的WebViewClient替换成BridgeWebViewClient

    webView.setWebViewClient(new BridgeWebViewClient(webView));
    
    private void registerHandler(MethodCall call) {
        final Map<String, Object> map = (Map<String, Object>) call.arguments;
        final String name = (String) map.get("name");
        if (name != null) {
            webView.registerHandler(name, new BridgeHandler() {
                @Override
                public void handler(String data, CallBackFunction function) {
                    Object response = map.get("response");
                    if (response != null) {
                        if (response instanceof HashMap) {
                            JSONObject jsonObject = new JSONObject((Map) response);
                            function.onCallBack(jsonObject.toString());
                        } else {
                            function.onCallBack((String) response);
                        }
                    }
                    JSONObject jsonObject = new JSONObject();
                    try {
                        jsonObject.put("name", name);
                        jsonObject.put("data", data);
                        methodChannel.invokeMethod("bridgeCallBack", jsonObject.toString());
                    } catch (JSONException e) {
                        Log.e("JsBridge", "json error");
                    }
                }
            });
        }
    }
    
    private void callHandler(MethodCall call) {
        final Map<String, Object> map = (Map<String, Object>) call.arguments;
        final String name = (String) map.get("name");
        if (name != null) {
            Object data = map.get("data");
            String dataStr = "";
            if (data != null) {
                if (data instanceof Map) {
                    JSONObject jsonObject = new JSONObject((Map) data);
                    dataStr = jsonObject.toString();
                } else {
                    dataStr = (String) data;
                }
            }
            webView.callHandler(name, dataStr, new CallBackFunction() {
                @Override
                public void onCallBack(String data) {
                    JSONObject jsonObject = new JSONObject();
                    try {
                        jsonObject.put("name", name);
                        jsonObject.put("data", data);
                        methodChannel.invokeMethod("bridgeCallBack", jsonObject.toString());
                    } catch (JSONException e) {
                        Log.e("JsBridge", "json error");
                    }
                }
            });
        }
    }
    

    具体源码

    使用

    通过flutter pub get加载依赖

    dependencies:
      bridge_webview_flutter: ^0.1.1
    

    onWebViewCreated方法里面通过webViewController调用

    ...
    body: Builder(builder: (BuildContext context) {
        return WebView(
            initialUrl: 'https://flutter.dev',
            javascriptMode: JavascriptMode.unrestricted,
            onWebViewCreated: (WebViewController webViewController) {
                _controller.complete(webViewController);
                webViewController.registerHandler("methodName", response: "r1", onCallBack: (callBackData) {      print(callBackData.name); // handler name
                    print(callBackData.data); // callback data ({'param': '1'})
                });
                webViewController.callHandler("methodName", data: "sendData", onCallBack: (callBackData) {
                    print(callBackData.name); // handler name
                    print(callBackData.data); // callback data (r2)
                });
            },
            onPageStarted: (String url) {
                print('Page started loading: $url');
            },
            onPageFinished: (String url) {
                print('Page finished loading: $url');
            },
            gestureNavigationEnabled: true,
        );
    }
    ...
    

    相关文章

      网友评论

        本文标题:Flutter使用JsBridge与WebView交互

        本文链接:https://www.haomeiwen.com/subject/zswlvhtx.html