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】:

【Flutter 混合开发】添加 Flutter 到 Android Activity的更多相关文章

  1. 【Flutter 混合开发】添加 Flutter 到 Android Fragment

    Flutter 混合开发系列 包含如下: 嵌入原生View-Android 嵌入原生View-iOS 与原生通信-MethodChannel 与原生通信-BasicMessageChannel 与原生 ...

  2. 【Flutter 混合开发】添加 Flutter 到 iOS

    Flutter 混合开发系列 包含如下: 嵌入原生View-Android 嵌入原生View-iOS 与原生通信-MethodChannel 与原生通信-BasicMessageChannel 与原生 ...

  3. Flutter混合开发:Android接入Flutter

    Flutter Google推出已经已经一年多了,单个 Flutter 项目的开发流程已经很成熟了.对与个人开发者来说使用 Flutter 开发一个跨平台的App挺有意思.但是对于现有的项目改造来说还 ...

  4. 【Flutter 混合开发】嵌入原生View-Android

    Flutter 混合开发系列 包含如下: 嵌入原生View-Android 嵌入原生View-IOS 与原生通信-MethodChannel 与原生通信-BasicMessageChannel 与原生 ...

  5. 【Flutter 混合开发】嵌入原生View-iOS

    Flutter 混合开发系列 包含如下: 嵌入原生View-Android 嵌入原生View-iOS 与原生通信-MethodChannel 与原生通信-BasicMessageChannel 与原生 ...

  6. 【Flutter 混合开发】与原生通信-MethodChannel

    Flutter 混合开发系列 包含如下: 嵌入原生View-Android 嵌入原生View-iOS 与原生通信-MethodChannel 与原生通信-BasicMessageChannel 与原生 ...

  7. 【Flutter 混合开发】与原生通信-BasicMessageChannel

    Flutter 混合开发系列 包含如下: 嵌入原生View-Android 嵌入原生View-iOS 与原生通信-MethodChannel 与原生通信-BasicMessageChannel 与原生 ...

  8. 【Flutter 混合开发】与原生通信-EventChannel

    Flutter 混合开发系列 包含如下: 嵌入原生View-Android 嵌入原生View-iOS 与原生通信-MethodChannel 与原生通信-BasicMessageChannel 与原生 ...

  9. flutter 混合开发

    flutter 混合开发 https://github.com/flutter/flutter/wiki/Add-Flutter-to-existing-apps https://flutter.de ...

随机推荐

  1. java学习从“菜鸟”到“放弃”

    今天学到java的对象和类中, 由于刚考完c++面向对象与程序设计这门课,对于c++中的类掌握自认为不错,就开始过渡到java. 今天面对的问题,在书写一个类的时候,发现了许多与c++不同的地方. 比 ...

  2. 小白也能看懂的Redis教学基础篇——redis神秘的数据结构

    各位看官大大们,周末好! 作为一个Java后端开发,要想获得比较可观的工资,Redis基本上是必会的(不要问我为什么知道,问就是被问过无数次).那么Redis是什么,它到底拥有什么神秘的力量,能获得众 ...

  3. 渗透测试方法论(qf总结)

    渗透测试(penetration testing , pentest)是实施安全评估(即审计)的具体手段.方法论是在指定.实施信息安全审计方案时,需要遵循的规则.惯例和过程.人们在评估网路.应用.系统 ...

  4. DevOps Next-AI / ML虚拟会议

    这个中秋国庆,一起进阶反超呀!10月1日星期四,加入DevOps Next,可以参加有关AI和ML的免费活动,内容涉及持续测试,代码质量和DevOps生产力.优秀的你一起来加入! 关于本次活动 Dev ...

  5. Apache HTTP Server 2.2.34安装

    Windows 下载 安装方式有自己编译源码和下载别人编译好的,这里选择从第三方下载,官网地址http://mirrors.tuna.tsinghua.edu.cn/apache//httpd/bin ...

  6. Centos-获取远程主机对应端口信息-telnet

    telnet 通过 telnet协议与远程主机通信或者获取远程主机对应端口信息 格式 telnet URL/IP port

  7. 02 Writing Your First Program 写你的第一个C程序

    Let's print "Hi" 打印输出"Hi" In your first computer program, let's print something ...

  8. sysfs是什么??

    来源:https://blog.csdn.net/qq_36412526/article/details/83751520 第一次接触:sysfs, 这里记录过程: 原文:Documenttation ...

  9. C#实现——十大排序算法之选择排序

    选择排序法 1.工作原理(算法思路) 给定一个待排序数组,找到数组中最小的那个元素 如果最小元素不是待排序数组的第一个元素,则将其和第一个元素互换 在剩下的元素中,重复1.2过程,直到排序完成. 2. ...

  10. 【转】Linux-CentOS7设置程序开启自启步骤!

    链接:https://blog.csdn.net/wang123459/article/details/79063703