首页 > 编程知识 正文

android,flutter与原生交互

时间:2023-05-06 00:27:37 阅读:154089 作者:3879

最近的项目需要在安卓本机APP应用程序中添加一些功能。 时间长,任务重,考虑再三。 只有安卓和Flutter混合在一起才能按时完成。 如上图所示,Android页面中有一个按钮需要跳转到Android,另一个按钮需要跳转到Flutter页面。 本文简要梳理了混合开发过程。 创建过滤器模块

在Android项目中单击“New”,然后单击“New Module”。 然后,在弹出面板中选择Flutter Module,输入Flutter Module的项目名称,选择Flutter SDK所在的路径,并选择Flutter Module文件的位置,最后选择Flutter Module

填写完上诉基本信息后,单击Next,然后在弹出面板中输入Flutter module包名称。 如下图所示

键入Package name,然后单击Finish以正式创建Flutter module。 创建的flutter module和新创建的flutter项目在内容上几乎没有差别。

2 .关联Flutter Module一般来说,当用户创建Flutter Module时,Android项目会自动关联您创建的Flutter Module。 可以在Android项目的settings.gradle上确认关联吗?

如果在开发过程中导入flutter module或直接使用其他flutter项目,则可以手动将其添加到settings.gradle中

setbinding(newbinding ) [gradle:this] ) evaluate ) newfile ) settingsdir, ' ./flutter _ module/. Android/include _ flutter.groovy ' ) (其中’./flutter _ module/. Android/include_flutter.groovy’是flutter module内include _ flutter.groovy的文件路径,flutter module所在的位置不一定在Android项目内

您还必须将dependencies添加到使用flutter module的Android module下的build.gradle中

implementationproject (path : ' : flutter ' )3.使用3. Android跳转到flutter页面直接跳转到FlutterActivity

在跳转之前,必须在AndroidManifest.xml中注册FlutterActivity。 activity Android 3360 name=' io.flutter.embedding.Android.flutter activity ' Android 3360 config changes=' orientation location loce 屏幕布局|硬件加速=' true ' Android 3360 app theme ' Android : windowsoftinpution

start activity (flutter activity.withnewengine ).initialroute ) ' Params ' ).build ) XXXactivity.this ); 其中initialRoute是安卓跳转到flutter所需的参数,不是必需的。

flutter的接收参数如下

. class _ myhomepagestateextendsstatemyhomepage { string route=window.default route name; } window.defaultRouteName是获取从Android传递的参数。 如果Android需要跳转到多个flutter页面,它通常用于路由分发,如果需要的信息很多,可以传递json字符串。 注: window.defaultRouteName的读包是“dart3360ui”,而不是“dart:html”。

FlutterActivity间接跳

间接跳转实际上是通过继承FlutterActivity实现的publicclasshybridextendsflutteractivity { publicfinalstaticstringparams=' params ' }

private String params; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); params = getIntent().getStringExtra(PARAMS); } @NonNull @Override public String getInitialRoute() { return params == null ? super.getInitialRoute() : params; } public static void toFlutter(Context context, String params) { Intent intent = new Intent(context, Hybrid.class); intent.putExtra(PARAMS, params); context.startActivity(intent); } }

在AndroidManifest.xm注册Hybrid后就可以通过

Hybrid.toFlutter(xxxxxActivity.this,"params");

进行跳转。

通过FlutterEngine和BasicMessageChannel进行跳转
为什么会有这种方式,是因为使用前两种方式跳转时会有短暂的空白,使用起来感觉非常不流畅,严重影响用户体验。这种跳转方式和上面的两种不同,边跳边发,适用于多种场景。这里也不一定非要使用BasicMessageChannel,也可使用MethodChannel或EventChannel,只是混合开发通常涉及到两端频繁通信,个人更加倾向使用BasicMessageChannel,不分主客,使用和通信更方便。 FlutterEngine和BasicMessageChannel的初始化和使用 public class HyBridRouteAndMessageHandleCenter{ private static FlutterEngine flutterEngine; private static BasicMessageChannel basicMessageChannel; private static String channelName = "com.hybrid.basic.message.channel"; public static final String ENGINE_ID = "default_engine_id"; private static Context mContext; private static BasicMessageChannel.Reply mReplay; public static void init(Context context) { mContext = context; if (flutterEngine == null) { flutterEngine = new FlutterEngine(context); flutterEngine.getDartExecutor().executeDartEntrypoint(DartExecutor.DartEntrypoint.createDefault()); FlutterEngineCache.getInstance().put(ENGINE_ID, flutterEngine); } if (basicMessageChannel == null) { if (flutterEngine != null) { basicMessageChannel = new BasicMessageChannel<Object>(flutterEngine.getDartExecutor(), channelName, StandardMessageCodec.INSTANCE); basicMessageChannel.setMessageHandler(new BasicMessageChannel.MessageHandler() { @Override public void onMessage(@Nullable @org.jetbrains.annotations.Nullable Object message, @NonNull @NotNull BasicMessageChannel.Reply reply) { mReplay = reply; // 接收消息并处理 handleMessage(message, reply); } }); } } } // 处理消息 private static void handleMessage(Object message, BasicMessageChannel.Reply reply) {... } public static void toFlutter(Context context, Object params) { sendMessage(params); context.startActivity(FlutterActivity.withCachedEngine(ENGINE_ID).build(context)); } public static void sendMessage(Object object) { if (basicMessageChannel != null) { basicMessageChannel.send(object, new BasicMessageChannel.Reply() { @Override public void reply(@Nullable @org.jetbrains.annotations.Nullable Object reply) { // 发送回调 ... } }); } } public static void destroyEngine() { if (flutterEngine != null) { flutterEngine.destroy(); } }} 使用FlutterActivity.withCachedEngine(ENGINE_ID).build(context)使因为从缓存中取更快,更省,而且只需要创建一个flutterEngine即可。Android端其实是可以创建多个flutterEngine,只要ENGINE_ID不同,就不是同一个flutterEngine,但是在iOS中只能有一个flutterEngine,使用多个会无效闪退,为了节省资源,避免过多损耗,全局使用一个flutterEngine比较好。关于Flutter向Android发送消息,比如flutter想拍照,拍完照后的图片路径需要传给flutter,照片的路径发送可以使用BasicMessageChannel.Reply回复,也可以使用sendMessage主动再发一次消息。个人认为接收消息并回复消息属于一次通信,所以倾向于使用BasicMessageChannel.Reply。若在Android端有多个页面需要向flutter回复结果,建议使用sendMessage。 Flutter收发消息 static const BasicMessageChannel messageChannel = const BasicMessageChannel( "com.hybrid.basic.message.channel", StandardMessageCodec()); static Future<dynamic> sendMessage(Object message) async{ dynamic result = await messageChannel.send(message); print("**********$result"); return result; } ... messageChannel.setMessageHandler((message) async { ... } ... sendMessage即flutter向Android端发送消息。比如拍照,拍完照后Android端通过BasicMessageChannel.Reply将图片路径reply.reply(imageUrl)给flutter,而flutter通过dynamic result = await messageChannel.send(message)接收回复的消息,其中result即为Android端返回imageUrl。messageChannel.setMessageHandler是Android主动向flutter发消息,flutter端的消息监听,通过解析message,可以知道Android需要flutter做什么,比如要跳转到什么页面,需要增删改什么数据等等。 4. 效果

5. 总结 1. 若熟练使用Flutter,混合开发可节省至少30%时间。 2. 直接使用FlutterActivity进行跳转,跳转过程中会出现空白间隙,建议使用FlutterEngineCache,效果更好。 3. 创建的Flutter Module不一定非要在Android项目中,可以在任意位置,关联正确就好。 注 :Android Studio 4.2.1,Android SDK 30 ,Flutter 2.2.0 , Dart 2.13.0。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。