

【Flutter 混合开发】添加 Flutter 到 Android Activity
source link: https://segmentfault.com/a/1190000037626943
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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:
Android 项目创建成功后,使用Android Studio 添加Flutter模块,在Android原生项目中点击“File > New > New Module...”,创建 Flutter Module :
注意 :Android Studio 的版本3.5及以上,Flutter IntelliJ plugin版本42及以上。
在弹出的选择Module类型的对话框中选中Flutter Module,然后点击Next,
设置Flutter module的Project name、Flutter SDK等,点击Next:
设置Flutter module的包名,点击Finish:
编译完成后将在当前App目录下生成Flutter模块的代码,目录结构如下:
启动页加载 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 页面
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>
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) ) } } }
引擎缓存
加载 FlutterActivity 页面时明显看到一段时间的黑屏,这段时间主要是启动 Flutter 引擎(FlutterEngine),Flutter 引擎启动的时间在不同手机上不同,性能越好的手机越短。同时每一个 FlutterActivity 页面都会启动一个引擎,所以强烈建议不要在一个项目中创建多个 FlutterActivity(或者启动多个 FlutterActivity 实例),否则内存会越来越大,下面是每隔3秒创建一个 FlutterActivity 实例内存变化图:
为了减少 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】:


Recommend
-
65
作者:腾讯NOW直播 -koudleren(任晓帅) 团队介绍 腾讯NOW终端技术团队在Flutter推出后就一直在关注Flutter的发展,并且在2018年4月份将Flutter引入到NOW直播APP中,在将Flutter运用在业务中的同事,也一直在研究并完
-
47
-
75
上一篇 Flutter混合开发:Android接入Flutter 我们讲到在 Flutter混合开发 中主要有、有 addView (页面局部Flutter) 和 s...
-
51
Flutter Google推出已经已经一年多了,单个 Flutter 项目的开发流程已经很成熟了。对与个人开发者来说使用...
-
43
找不到页面 - 掘金
-
15
混合开发简介 使用Flutter从零开始开发App是一件轻松惬意的事情,但对于一些成熟的产品来说,完全摒弃原有App的历史沉淀,全面转向Flutter是不现实的。因此使用Flutter去统一Android、iOS技术栈,把它作为已有原生App的扩展能...
-
23
flutter 1. 简介 Flutter Boost 是闲鱼团队开发的一个 Flutter 混合开发框架,项目背景可以看看闲鱼的这...
-
17
自上篇 Flutter 10天高仿大厂App及小技巧积累总结 的续篇,这次更是干货满满。 ...
-
25
Flutter 混合开发系列 包含如下: 嵌入原生View-Android 嵌入原...
-
20
Flutter 混合开发系列 包含如下: 嵌入原生View-Android 嵌入原生View-iOS 与原生通...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK