原文链接:[https://flutter.dev/docs/development/add-to-app](https://flutter.dev/docs/development/add-to-app)
# 概述
使用Flutter对我们现有的应用进行重构并不是一件容易的事,针对这种情况,Flutter可以分次以库或模块的形式集成到现有应用,在应用中可以对部分UI使用Flutter进行渲染。仅仅通过简单的几部,就可以在我们现有应用中引入Flutter强大的功能。
在FlutterV1.12版本中,支持将全屏Flutter实例添加到现有应用中,目前有以下限制:
* 运行多个Flutter实例或局部Flutter UI可能会有不稳定的表现
* 在后台模式下使用Flutter依旧不成熟
* 暂不支持打包Flutter库到另一个库,以及集成多个Flutter库到一个应用中
## 已支持的功能
### 添加Flutter到Android应用中
* 在gradle脚本文件中添加相关配置即可自动引入和构建Flutter模块
*
### 添加Flutter到iOS应用中
略
# 添加Flutter到现有应用
## 基础配置
Flutter可以借助gradle脚本以源码形式集成到现有应用中,也可以使用aar形式集成到现有应用。可以使用Android Studio提供的插件来集成,也可以用命令行来手动集成。
> 注意:现有应用可能会支持mips和x86/x86_64架构,但Flutter目前使用AOT模式编译库仅支持armeabi-v7a和arm64-v8a架构,因此建议在gradle文件中使用abiFilters来限制支持的架构平台,来避免出现丢失libflutter.so运行时异常。相关配置示例如下:
```gradle
android {
//...
defaultConfig {
ndk {
// Filter for architectures supported by Flutter.
abiFilters 'armeabi-v7a', 'arm64-v8a'
}
}
}
```
Flutter引擎有x86和x86_64版本,所以在使用模拟器调试时,Flutter会以JIT模式进行编译运行。
### 使用Android Studio集成Flutter
使用Android Studio可以很方便的集成Flutter,借助Android Studio,可以将Android代码和Flutter代码放到一个文件目录下,可以继续正常使用IntelliJ的系列插件如Dart代码补全、热重载、Widget分析器等等。‘
使用Android Studio集成Flutter需要Android Studio版本在3.6以上,Flutter IntelliJ插件版本在42以上。目前仅支持使用gradle脚本和源码的方式集成,暂不支持使用aar的形式。
打开现有应用项目,在Android Studio的菜单`File > New > New Module...`中,可以选择创建一个新的Flutter Module或选择已存在的Flutter Module。
如果选择创建新的Flutter Module,可以在向导中配置该Module的名字、路径等信息。
Android Studio插件会自动配置现有应用项目来依赖Flutter Module,现在项目已经可以进行构建了。
tip:在项目Project视图下可以看到Flutter文件目录,如果看不到可能是以Android视图查看的,调整视图即可。
### 使用命令行手动集成Flutter
## 添加一个简单Flutter Screen
下面介绍如何添加一个Flutter Screen到现有应用中,Flutter Screen可以有普通的、不透明的、可透视的以及透明的几种形式。
### 添加一个普通的Screen
#### 1、添加FlutterActivity到清单文件中
在Android应用中,Flutter提供FlutterActivity来显示相关UI,和其他普通Activity一样,FlutterActivity必须在清单文件中进行注册,示例如下:
```xml
<activity
android:name="io.flutter.embedding.android.FlutterActivity"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"
/>
```
其中theme属性的`@style/LaunchTheme`可以替换成其他任何普通的theme,theme的设定和Android系统的Chrome有关?如导航栏。
#### 2、导航到FlutterActivity
在添加完清单文件后,可以在任何时候导航到FlutterActivity了,示例如下:
```java
myButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startActivity(
FlutterActivity.createDefaultIntent(currentActivity)
);
}
});
```
上面的示例假设了Dart代码的入口点在main()方法,Flutter路由路径是`/`。Dart代码的入口点并不能通过Intent来更改,但是初始化路由是可以通过Intent来更改的,下面的示例演示了如何更改初始化路由:
```java
myButton.addOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startActivity(
FlutterActivity
.withNewEngine()
.initialRoute("/my_route")
.build(currentActivity)
);
}
});
```
可以通过替换`/my_route`来更改期望的初始化路由。
使用withNewEngine() 方法,创建了拥有自己的FlutterEngine实例的FlutterActivity对象,这带来一个FlutterEngine初始化耗时问题,优化的方法是预加载并缓存FlutterEngine,创建FlutterActivity对象时就无需再初始化FlutterEngine,来最小化FlutterActivity的耗时问题,关于此问题下文将会详述。
#### 3、(可选)缓存FlutterEngine
默认情况下,每一个FlutterActivity都会创建自己的FlutterEngine对象,每一个FlutterEngine都需要加载耗时,也就是说打开每一个标准的FlutterActivity时都会有一个延迟。为了减少这个延迟,可以在打开FlutterActivity前预加载FlutterEngine,需要使用的时候直接使用预加载好的FlutterEngine。
需要找一个合适的地方来预加载FlutterEngine,下面的示例在Application代码中进行预加载:
```java
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
// Instantiate a FlutterEngine.
flutterEngine = new FlutterEngine(this);
// Start executing Dart code to pre-warm the FlutterEngine.
flutterEngine.getDartExecutor().executeDartEntrypoint(
DartEntrypoint.createDefault()
);
// Cache the FlutterEngine to be used by FlutterActivity.
FlutterEngineCache
.getInstance()
.put("my_engine_id", flutterEngine);
}
}
```
传递给FlutterEngineCache的id可以是任意值,只要确保和在FlutterActivity和FlutterFragment中取出FlutterEngine时使用的一致即可。下面来看看如何使用缓存的FlutterEngine。
```java
myButton.addOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startActivity(
FlutterActivity
.withCachedEngine("my_engine_id")
.build(currentActivity)
);
}
});
```
当使用withCachedEngine方法时,注意id要和预加载FlutterEngine时保持一致。现在再打开FlutterActivity时,延迟问题就好很多了。
### 添加一个透明的Flutter Screen
大部分的Flutter UI是不透明的,但是有时候需要显示成部分UI,比如Dialog、底部sheet等,Flutter支持透明的FlutterActivity。接下来看看如何实现透明的FlutterActivity。
#### 1、使用透明主题
Android中需要使用特殊的属性来渲染透明背景,如下:
```xml
<style name="MyTheme" parent="@style/MyParentTheme">
<item name="android:windowIsTranslucent">true</item>
</style>
```
```xml
<activity
android:name="io.flutter.embedding.android.FlutterActivity"
android:theme="@style/MyTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"
/>
```
现在FlutterActivity支持了透明显示了,接下来在打开时需要明确设置透明模式。
#### 2、打开透明的FlutterActivity
打开透明背景的FlutterActivity,需要传递适当的BackgroundMode值给IntentBuilder,示例如下:
```java
// Using a new FlutterEngine.
startActivity(
FlutterActivity
.withNewEngine()
.backgroundMode(FlutterActivity.BackgroundMode.transparent)
.build(context)
);
// Using a cached FlutterEngine.
startActivity(
FlutterActivity
.withCachedEngine("my_engine_id")
.backgroundMode(FlutterActivity.BackgroundMode.transparent)
.build(context)
);
```
现在就拥有了一个背景透明的FlutterActivity了。
## 添加一个Flutter Fragment
## 添加一个闪屏
- 导读
- Java知识
- Java基本程序设计结构
- 【基础知识】Java基础
- 【源码分析】Okio
- 【源码分析】深入理解i++和++i
- 【专题分析】JVM与GC
- 【面试清单】Java基本程序设计结构
- 对象与类
- 【基础知识】对象与类
- 【专题分析】Java类加载过程
- 【面试清单】对象与类
- 泛型
- 【基础知识】泛型
- 【面试清单】泛型
- 集合
- 【基础知识】集合
- 【源码分析】SparseArray
- 【面试清单】集合
- 多线程
- 【基础知识】多线程
- 【源码分析】ThreadPoolExecutor源码分析
- 【专题分析】volatile关键字
- 【面试清单】多线程
- Java新特性
- 【专题分析】Lambda表达式
- 【专题分析】注解
- 【面试清单】Java新特性
- Effective Java笔记
- Android知识
- Activity
- 【基础知识】Activity
- 【专题分析】运行时权限
- 【专题分析】使用Intent打开三方应用
- 【源码分析】Activity的工作过程
- 【面试清单】Activity
- 架构组件
- 【专题分析】MVC、MVP与MVVM
- 【专题分析】数据绑定
- 【面试清单】架构组件
- 界面
- 【专题分析】自定义View
- 【专题分析】ImageView的ScaleType属性
- 【专题分析】ConstraintLayout 使用
- 【专题分析】搞懂点九图
- 【专题分析】Adapter
- 【源码分析】LayoutInflater
- 【源码分析】ViewStub
- 【源码分析】View三大流程
- 【源码分析】触摸事件分发机制
- 【源码分析】按键事件分发机制
- 【源码分析】Android窗口机制
- 【面试清单】界面
- 动画和过渡
- 【基础知识】动画和过渡
- 【面试清单】动画和过渡
- 图片和图形
- 【专题分析】图片加载
- 【面试清单】图片和图形
- 后台任务
- 应用数据和文件
- 基于网络的内容
- 多线程与多进程
- 【基础知识】多线程与多进程
- 【源码分析】Handler
- 【源码分析】AsyncTask
- 【专题分析】Service
- 【源码分析】Parcelable
- 【专题分析】Binder
- 【源码分析】Messenger
- 【面试清单】多线程与多进程
- 应用优化
- 【专题分析】布局优化
- 【专题分析】绘制优化
- 【专题分析】内存优化
- 【专题分析】启动优化
- 【专题分析】电池优化
- 【专题分析】包大小优化
- 【面试清单】应用优化
- Android新特性
- 【专题分析】状态栏、ActionBar和导航栏
- 【专题分析】应用图标、通知栏适配
- 【专题分析】Android新版本重要变更
- 【专题分析】唯一标识符的最佳做法
- 开源库源码分析
- 【源码分析】BaseRecyclerViewAdapterHelper
- 【源码分析】ButterKnife
- 【源码分析】Dagger2
- 【源码分析】EventBus3(一)
- 【源码分析】EventBus3(二)
- 【源码分析】Glide
- 【源码分析】OkHttp
- 【源码分析】Retrofit
- 其他知识
- Flutter
- 原生开发与跨平台开发
- 整体归纳
- 状态及状态管理
- 零碎知识点
- 添加Flutter到现有应用
- Git知识
- Git命令
- .gitignore文件
- 设计模式
- 创建型模式
- 结构型模式
- 行为型模式
- RxJava
- 基础
- Linux知识
- 环境变量
- Linux命令
- ADB命令
- 算法
- 常见数据结构及实现
- 数组
- 排序算法
- 链表
- 二叉树
- 栈和队列
- 算法时间复杂度
- 常见算法思想
- 其他技术
- 正则表达式
- 编码格式
- HTTP与HTTPS
- 【面试清单】其他知识
- 开发归纳
- Android零碎问题
- 其他零碎问题
- 开发思路