Flutter使用JsBridge与WebView交互
2020-04-16 本文已影响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,
);
}
...