前言:前段时间做了个flutter项目,过程中老板想要将flutter内部的部分模块加入到我们自己以前原生的项目内,本人负责Android这变得嵌入,所以讲一下Android部分内容理解。官方文档讲的很清晰,我这边大部分都是根据他搞得,所以也一起粘贴了。因flutter嵌原生有内存泄漏问题,本人使用的是aar打包方式,貌似没出现泄漏,不过我这边对引擎做的处理也会Android模块末尾粘贴。
参考网站:https://flutter.cn/docs/development/add-to-app/android/add-flutter-screen
一,Android端
1.声明引擎,Android端MethodChannel名称
private FlutterEngine flutterEngine;
private static final String BATTERY_CHANNEL = "flutter.back";
2,在Active初始化方法内对引擎进行初始化赋值
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
flutterEngine = new FlutterEngine(this);
//定义默认加载路由页面
flutterEngine.getNavigationChannel().setInitialRoute("customerDetail");
flutterEngine.getDartExecutor().executeDartEntrypoint(
DartExecutor.DartEntrypoint.createDefault()
);
//提前声明引擎,防止加载时黑屏时间过长
FlutterEngineCache
.getInstance()
.put("my_engine_id", flutterEngine);
//这是flutter端定义的MethodChannel方法,我们可以提前将token,请求地址先传过去,这样之后再做点击操作再传递对应的动态参数
methodChannelFlutter = new MethodChannel(flutterEngine.getDartExecutor(),"flutter.platform");
String _token = "token";
String _HostUrl = "hostUrl";
Map params = new HashMap();
params.put("mToken", _token);
params.put("mHostUrl", _HostUrl);
methodChannelFlutter.invokeMethod("relyData",params);
}
//配置我们声明的引擎
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
new MethodChannel(flutterEngine.getDartExecutor(), BATTERY_CHANNEL).setMethodCallHandler(
new MethodChannel.MethodCallHandler() {
//在这监听flutter端返回的数据,Android端做出对应的操作
@Override
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
if (call.method.equals("goBackWithResult")) {
finishActivity(100);
if(call.argument("isEdit")){
onRefresh(null);
}
} else if(call.method.equals("loginTimeOut")){
finishActivity(100);
}else {
result.notImplemented();
}
}
}
);
}
3,Android端跳转到flutter端交互
Map params = new HashMap();
params.put("faceID","faceID");
configureFlutterEngine(flutterEngineFace);
//通过flutter端定义的MethodChannel,将Android端数据传进去
methodChannelFlutter.invokeMethod("faceData", params);
//这里使用了startActivityForResult方法跳转,因为当时在开发时遇到个关闭flutter页面的坑,有时间的小伙伴可以换种方式试试其他方式,有人对这个坑有兴趣可在评论区提出,我会做出回答
startActivityForResult(
FlutterActivity
.withCachedEngine("my_engine_face")
.backgroundMode(FlutterActivityLaunchConfigs.BackgroundMode.transparent)
.build(getContext()),100);
4,移除Android端声明引擎,
@Override
protected void onDestroy() {
if(flutterEngine != null){
FlutterActivity.withCachedEngine("my_engine_id").destroyEngineWithActivity(true);
methodChannelFlutter.setMethodCallHandler(null);
methodChannelFlutter = null;
FlutterEngineCache.getInstance().remove("my_engine_id"); flutterEngine.destroy();
flutterEngine = null;
}
super.onDestroy();
}
二,flutter端
1.声明flutter端MethodChannel
static MethodChannel mPlatformChannel = const MethodChannel('flutter.platform'); //Method数据信息通道
2,在初始化方法内调用MethodChannel
@override
void initState() {
super.initState();
platformChannel();
}
//Native模块通道方法
void platformChannel(){
mPlatformChannel.setMethodCallHandler((methodCall) async {
switch (methodCall.method) {
case "relyData":
String _token = await methodCall.arguments['token'];
String _HostUrl = await methodCall.arguments['hostUrl'];
break;
case "faceData":
String _faceID = await methodCall.arguments['faceID'];
break;
default:
throw MissingPluginException();
}
});
}
flutter端只要接收数据,并对数据做出对应的交互处理就可以了。
结尾
以上的代码,一个引擎运行起我们需要的一个模块已经是完全没问题了,那么如何一个引擎运行多个模块呢?最近再看这块,有找到一个解决方法,等运用到项目上时我再更新一篇文章。