注册

Native 如何快速集成 Flutter

如何 Android 项目中集成 Flutter


概述


目前flutter越来越受欢迎,但对于一些成熟的产品来说,完全摒弃原有App全面转向Flutter是不现实的。因此使用Flutter去统一Android、iOS技术栈,把它作为已有原生App的扩展能力,通过有序推进来提升移动终端的开发效率。 目前,想要在已有的原生App里嵌入一些Flutter页面主要有两种方案。一种是将原生工程作为Flutter工程的子工程,由Flutter进行统一管理,这种模式称为统一管理模式。另一种是将Flutter工程作为原生工程的子模块,维持原有的原生工程管理方式不变,这种模式被称为三端分离模式,如下图所示。
1.png
三端代码分离模式的原理是把Flutter模块作为原生工程的子模块,从而快速地接入Flutter模块,降低原生工程的改造成本。


如何在Native项目中接入flutter 模块


在原生项目中集成flutter模块有两种方式,第一种是直接在项目中新建一个flutter module,第二种将flutter项目模块打包成aar或so包集成到Native项目中。一下将详细介绍这两种方式 (以Android为例)


采用module引用的方式


直接通过Android stuido



File->New ->New Module 选择 Flutter Module 来生成一个Flutter Module.



image.png


image.png



如下图:Android studio为原生项目创建了一个module



image.png


手动创建Flutter module


假设你在 some/path/MyApp 路径下已有一个 Android 应用,并且你希望 Flutter 项目作为同级项目:


 cd some/path/
$ flutter create -t module --org com.example my_flutter

image.png


注意:



  1. 这会创建一个 some/path/my_flutter/ 的 Flutter 模块项目,其中包含一些 Dart 代码来帮助你入门以及一个隐藏的子文件夹 .android/。 .android 文件夹包含一个 Android 项目,该项目不仅可以帮助你通过 flutter run 运行这个 Flutter 模块的独立应用,而且还可以作为封装程序来帮助引导 Flutter 模块作为可嵌入的 Android 库。
  2. 为了避免 Dex 合并出现问题,flutter.androidPackage 不应与应用的包名相同

引入 Java 8


Flutter Android 引擎需要使用到 Java 8 中的新特性。


在尝试将 Flutter 模块项目集成到宿主 Android 应用之前,请先确保宿主 Android 应用的 build.gradle 文件的 android { } 块中声明了以下源兼容性,例如:


android {
//...
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}
}

采用AAR资源包的方式导入Flutter模块


flutter 工程作为独立的项目开发迭代,原生工程不直接使用Flutter项目,而是通过导入flutter 的资源包来引用Flutter 模块。



创建Flutter module 工程。



image.png



编译生成AAR包



image.png



flutter 工程会创建一个本地maven仓库和aar文件,同时在Flutter 项目也会输出指引导入的步骤文本,按照提示步骤操作即可。
为方便使用将该maven仓库拷贝到native 项目中。



image.png



提示步骤如下



Consuming the Module




  1. Open \app\build.gradle




  2. Ensure you have the repositories configured, otherwise add them:


    String storageUrl = System.env.FLUTTER_STORAGE_BASE_URL ?: "storage.googleapis.com"
    repositories {
    maven {
    url 'D:<path>\build\host\outputs\repo'
    }
    maven {
    url '$storageUrl/download.flutter.io'
    }
    }




  3. Make the host app depend on the Flutter module:




dependencies {
debugImplementation 'com.example.untitled1:flutter_debug:1.0'
profileImplementation 'com.example.untitled1:flutter_profile:1.0'
releaseImplementation 'com.example.untitled1:flutter_release:1.0'
}


  1. Add the profile build type:

android {
buildTypes {
profile {
initWith debug
}
}
}

To learn more, visit flutter.dev/go/build-aa…
Process finished with exit code 0


在 Android 应用中添加 Flutter 页面


步骤 1:在 AndroidManifest.xml 中添加 FlutterActivity


Flutter 提供了 FlutterActivity,用于在 Android 应用内部展示一个 Flutter 的交互界面。和其他的 Activity 一样,FlutterActivity 必须在项目的 AndroidManifest.xml 文件中注册。将下边的 XML 代码添加到你的 AndroidManifest.xml 文件中的 application 标签内:


<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"
/>

上述代码中的 @style/LaunchTheme 可以替换为想要在你的 FlutterActivity 中使用的其他 Android 主题。主题的选择决定 Android 系统展示框架所使用的颜色,例如 Android 的导航栏,以及 Flutter UI 自身的第一次渲染前 FlutterActivity 的背景色。


步骤 2:加载 FlutterActivity


在你的清单文件中注册了 FlutterActivity 之后,根据需要,你可以在应用中的任意位置添加打开 FlutterActivity 的代码。下边的代码展示了如何在 OnClickListener 的点击事件中打开 FlutterActivity


myButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startActivity(
FlutterActivity.createDefaultIntent(currentActivity)
);
}
});

Flutter 启动优化


每一个 FlutterActivity 默认会创建它自己的 FlutterEngine。每一个 FlutterEngine 会有一个明显的预热时间。这意味着加载一个标准的 FlutterActivity 时,在你的 Flutter 交互页面可见之前会有一个短暂的延迟。想要最小化这个延迟时间,你可以在抵达你的 FlutterActivity 之前,初始化一个 FlutterEngine,然后使用这个已经预热好的 FlutterEngine
如果直接启动FlutterActivity则无法避免预热时间,用户会感受到一个较长时间的白屏等待。


优化


提前初始化一个  FlutterEngine,启动的FlutterActivty时直接使用已经初始化的FlutterEngine.



提前初始化



public class MyApplication extends Application {
public FlutterEngine flutterEngine;

@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);
}
}


使用预热的FlutterEngine



myButton.addOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startActivity(
FlutterActivity
.withCachedEngine("my_engine_id")
.build(currentActivity)
);
}
});

作者:hujian
链接:https://juejin.cn/post/7113874811675213832
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

0 个评论

要回复文章请先登录注册