💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
原文链接:[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 ## 添加一个闪屏