【Flutter 混合开发】添加 Flutter 到 Android Activity

2023-01-28 0 766

【Flutter 混合开发】添加 Flutter 到 Android Activity

Flutter 混和合作开发系列产品 包涵如下表所示:

内嵌原生植物View-Android 内嵌原生植物View-iOS 与原生植物通讯-MethodChannel 与原生植物通讯-BasicMessageChannel 与原生植物通讯-EventChannel加进 Flutter 到 Android Activity加进 Flutter 到 Android Fragment 加进 Flutter 到 iOS

每一休息日撷取一则,热烈欢迎关注、点赞及转贴。

建立 Flutter Module

Flutter能以源码或AAR的方式内嵌到Android原生植物工程项目,软件系统业务流程能采用 Android Studio 顺利完成,也能全自动顺利完成。雷西县采用 Android Studio。

具体来说建立两个 Android 工程项目,建立两个空的 Activity:

【Flutter 混合开发】添加 Flutter 到 Android Activity

Android 工程项目建立获得成功后,采用Android Studio 加进Flutter组件,在Android原生植物工程项目中点选“File > New > New Module…”,建立Flutter Module

【Flutter 混合开发】添加 Flutter 到 Android Activity

特别注意:Android Studio 的版3.5及以内,Flutter IntelliJ plugin版42及以内。

在插入的优先选择Module类别的页面中选上Flutter Module,接着点选Next,

【Flutter 混合开发】添加 Flutter 到 Android Activity

增设Flutter module的Project name、Flutter SDK等,点选Next:

【Flutter 混合开发】添加 Flutter 到 Android Activity

增设Flutter module的包名,点选Finish:

【Flutter 混合开发】添加 Flutter 到 Android Activity

编译顺利完成后将在当前App目录下生成Flutter组件的代码,目录结构如下表所示:

【Flutter 混合开发】添加 Flutter 到 Android Activity

启动页加载 Flutter

将 Flutter 页面加载到 MainActivity(默认启动页) 中,修改 MainActivity :

package com.flutter.androidflutter import io.flutter.embedding.android.FlutterActivity class MainActivity : FlutterActivity()

你没有看错,只需让 MainActivity 继承 FlutterActivity 即可。

特别注意:FlutterActivity的包名是io.flutter.embedding.android.FlutterActivity

【Flutter 混合开发】添加 Flutter 到 Android Activity

跳转到 Flutter 页面

MainActivity(默认启动页)加进两个按钮,点选后跳转到新的页面,此页面加载 Flutter ,MainActivity代码如下:

package com.flutter.androidflutter import android.content.Intent import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import io.flutter.embedding.android.FlutterActivity import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) button.setOnClickListener { startActivity(Intent(this,SecondFlutterActivity::class.java)) } } }

SecondFlutterActivity 代码如下表所示:

package com.flutter.androidflutter import io.flutter.embedding.android.FlutterActivity class SecondFlutterActivity:FlutterActivity()

AndroidManifest.xml 中注册此 Activity:

<?xml version=”1.0″ encoding=”utf-8″?> <manifest xmlns:android=”http://schemas.android.com/apk/res/android” package=”com.flutter.androidflutter”> <application android:allowBackup=”true” android:icon=”@mipmap/ic_launcher” android:label=”@string/app_name” android:roundIcon=”@mipmap/ic_launcher_round” android:supportsRtl=”true” android:theme=”@style/AppTheme”> … <activity android:name=”.SecondFlutterActivity”/> </application> </manifest>
【Flutter 混合开发】添加 Flutter 到 Android Activity

SecondFlutterActivity 只是继承了 FlutterActivity,这种情况下,也能直接采用 FlutterActivity

startActivity(Intent(this, FlutterActivity::class.java))

或者:

startActivity(FlutterActivity.createDefaultIntent(this))

AndroidManifest.xml中注册 FlutterActivity:

<activity android:name=”io.flutter.embedding.android.FlutterActivity”/>

效果与上面是一样的。

FlutterActivity 会加载 Flutter Module 中 lib/main.dart 中 main 方式,如果有多个Flutter页面,如何指定跳转,比如现在有 OnePage Flutter 页面,OnePage 代码如下表所示:

class OnePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(), body: Center( child: Text(这是 One 页面), ), ); } }

FlutterActivity 指定加载页面需要采用命名路由,MyApp 修改如下表所示:

class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: Flutter Demo, theme: ThemeData( primarySwatch: Colors.blue, ), routes: { one_page:(context){ return OnePage(); }, two_page:(context){ return TwoPage(); } }, home: MyHomePage(title: Flutter Demo Home Page), ); } }

MainActivity 页面点选到 Flutter 页面,加载 OnePage 页面:

class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) button.setOnClickListener { startActivity( FlutterActivity .withNewEngine() .initialRoute(“one_page”) .build(this) ) } } }
【Flutter 混合开发】添加 Flutter 到 Android Activity

引擎缓存

加载 FlutterActivity 页面时明显看到一段时间的黑屏,这段时间主要是启动 Flutter 引擎(FlutterEngine),Flutter 引擎启动的时间在不同手机上不同,性能越好的手机越短。同时每两个 FlutterActivity 页面都会启动两个引擎,所以雷西县不要在两个工程项目中建立多个 FlutterActivity(或者启动多个 FlutterActivity 实例),否则内存会越来越大,下面是每隔3秒建立两个 FlutterActivity 实例内存变化图:

【Flutter 混合开发】添加 Flutter 到 Android Activity

为了减少 FlutterActivity 页面的延迟时间和多个 FlutterActivity 实例内存一直增长问题,我们能采用 Flutter 引擎(FlutterEngine)缓存,在启动 FlutterActivity 前先启动 Flutter 引擎,然后采用缓存的引擎加载页面,通常将其放在Application 中:

class MyApplication : Application() { lateinit var flutterEngine: FlutterEngine override fun onCreate() { super.onCreate() flutterEngine = FlutterEngine(this) flutterEngine.dartExecutor.executeDartEntrypoint( DartExecutor.DartEntrypoint.createDefault() ) FlutterEngineCache .getInstance() .put(“engine_id”, flutterEngine) } }

采用缓存的引擎:

startActivity( FlutterActivity .withCachedEngine(“engine_id”) .build(this) )

在同一台手机上效果非常明显,黑屏时间大大减少,不过还是有一个短暂的黑屏。

这里要特别注意,采用缓存引擎时,其生命周期不在是 FlutterActivity(或者 FlutterFragment)的生命周期,而是整个 App 的生命周期(在Application 中的建立和销毁)。当然也能提前销毁:

flutterEngine.destroy()

另外工程项目的 debug 和 release 版对性能的影响非常大,如果要测试其性能一定在要 release 下测试

上面采用新的引擎能指定 FlutterActivity(或者 FlutterFragment)配置初始路由,但采用缓存引擎时无法在 FlutterActivity(或者 FlutterFragment)配置初始路由,因为缓存引擎已经启动并运行,不过能在启动缓存引擎时指定其初始路由:

flutterEngine = FlutterEngine(this) flutterEngine.navigationChannel.setInitialRoute(“one_page”) flutterEngine.dartExecutor.executeDartEntrypoint( DartExecutor.DartEntrypoint.createDefault() ) FlutterEngineCache .getInstance() .put(“engine_id”, flutterEngine)

如果采用缓存引擎在FlutterActivity(或 FlutterFragment)指定不同路由,如何处理?这时需要建立两个method channel,flutter 接收具体消息从而切换不同的路由。

交流

老孟Flutter博客(330个控件用法+实战入门系列产品文章):http://laomengit.com

热烈欢迎加入Flutter交流群(微信:laomengit)、关注公众号【老孟Flutter】

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务