Flutter web app三端跨平台双向桥接dart web开发

Flutter web app三端跨平台双向桥接dart web开发

环境及项目运行步骤:

1、安装开发工具webstorm
2、官网下载flutter stable-1.5.4,安装好并配置环境变量
3、执行cmd命令:pub global activate webdev
4、执行cmd命令:pub global activate stagehand
5、创建好Flutter web app项目,在配置文件里引入js库如下
6、项目运行命令:webdev serve -r hostname 0.0.0.0,成功后浏览器访问 127.0.0.1:8080
(项目打包命令webdev build -r,成功后将build目录拷贝到tomcat部署就行了)
参考:
https://pub.dev/packages/webdev
https://flutterchina.club/setup-windows/
https://blog.csdn.net/yuzhiqiang_1993/article/details/84939634
https://blog.csdn.net/jay100500/article/details/88562450

#文件名:pubspec.yaml
name: test_flutter_web
description: An app built using Flutter for web

environment:
  # You must be using Flutter >=1.5.0 or Dart >=2.3.0
  sdk: '>=2.3.0-dev.0.1 <3.0.0'

dependencies:
  js: any
  flutter_web: any
  flutter_web_ui: any

dev_dependencies:
  build_runner: ^1.4.0
  build_web_compilers: ^2.0.0
  pedantic: ^1.0.0

dependency_overrides:
  flutter_web:
    git:
      url: https://github.com/flutter/flutter_web
      path: packages/flutter_web
  flutter_web_ui:
    git:
      url: https://github.com/flutter/flutter_web
      path: packages/flutter_web_ui

一、下面是dart web的写法

1. Android/iOS/chrome 调用dart web页面
// 文件名:bridge_util.dart
import "package:js/js.dart"; 
import "dart:html"; 
import "dart:js"; 
import 'package:js/js_util.dart' as js_util; 
var bridge; 
//这里往window窗口写入bridge对象
bool checkBridge(){ 
	if(bridge == null) { 
		js_util.setProperty(window, "bridge", new Object()); 
		bridge = js_util.getProperty(window, "bridge"); 
	} 
	return bridge != null; 
} 
//Android/iOS/web调用dart,本质是往bridge写入一个函数
void registerBridge(String name, void Function(String) callback){ 
	if(checkBridge()) { 
		js_util.setProperty(bridge, name, allowInterop(callback)); 
	} 
}

调用方法

//使用的文件中引入
import "bridge_util.dart";
//定义一个方法
void callbackTest(event){
    print("回调来了"+event.toString());
  }
//直接调用注册一个回调函数
registerBridge("show",callbackTest);
//测试下:可以通过浏览器的控制台输入window.bridge.show("我来自浏览器")
2. dart web页面调用Android/iOS/chrome
//文件名:bridge_call.dart
//参考:https://pub.dev/packages/js
//参考:https://github.com/matanlurey/dart_js_interop
//参考:https://dart.dev/web/js-interop
import "package:js/js.dart";

//dart调用web
@JS("JSON.stringify")
external String stringify(obj);

//dart调用web
@JS("window.alert")
external void alert(obj);

//dart调用iOS带参数
@JS("window.webkit.messageHandlers.setCookies.postMessage")
external void setCookies(obj);

//dart调用iOS
@JS("window.webkit.messageHandlers.getIMEI.postMessage")
external String getIMEI();

//dart调用Android带参数
@JS("window.bridge.getIMEI")
external String getIMEI();

//dart调用Android
@JS("window.bridge.setCookies")
external void setCookies(obj);

调用方法

//使用的文件中引入
import "bridge_call.dart";
//直接调用传参或取值
setCookies("这里传参");
var imei = getIMEI();
print("iemi:"+imei);

另外一种用法

import 'package:js/js_util.dart' as js;
var o = js.getProperty(window, "bridge");
js.callMethod(o, "setCookies", ["这里传参"]);
var imei = js.callMethod(o, "getIMEI");
print("iemi:"+imei);

二、下面是Android端写法

//Android调用js(等价于调用dart web)
webView.loadUrl("javascript:bridge.setCookies('" + cookies + "')");
或 webView.eveluatejavascript("javascript:bridge.setCookies('" + cookies + "')");
--------------------- 
//js(等价于dart web)调用Android
webView.addJavascriptInterface(new JSHook(), "bridge");
--------------------- 
//参考: https://blog.csdn.net/u010568885/article/details/70737956

三、下面是iOS端写法

// iOS调用js (等价于调用dart web)
NSString *jsStr = [NSString stringWithFormat:@"bridge.setCookies('%@','%@','%@')",title,content,url]; 
[self.webView evaluateJavaScript:jsStr completionHandler:^(id _Nullable result, NSError * _Nullable error) 
{ NSLog(@"%@----%@",result, error); }];
--------------------- 
//js(等价于dart web)调用iOS
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
configuration.userContentController = [WKUserContentController new];
[configuration.userContentController addScriptMessageHandler:self name:@"getIMEI"];
[configuration.userContentController addScriptMessageHandler:self name:@"setCookies"];
WKPreferences *preferences = [WKPreferences new];
preferences.javaScriptCanOpenWindowsAutomatically = YES;
preferences.minimumFontSize = 40.0;
configuration.preferences = preferences;
--------------------- 
#pragma mark - WKScriptMessageHandler - (void)userContentController:
(WKUserContentController *)userContentController didReceiveScriptMessage:
(WKScriptMessage *)message { 
	// message.body -- Allowed types are NSNumber, 
	// NSString, NSDate, NSArray,NSDictionary, and NSNull. 
	if ([message.name isEqualToString:@"getIMEI"]) {
	 	[self getIMEI]; 
	 } 
	else if ([message.name isEqualToString:@"setCookies"]) { 
		[self setCookies:message.body]; 
	} 
}
--------------------- 
//参考:https://blog.csdn.net/u011619283/article/details/52135988 

版权声明:本文为ypppk原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。