写点什么

【Flutter 专题】77 图解历史 Android Native 项目接入 Flutter Module

发布于: 3 小时前
【Flutter 专题】77 图解历史 Android Native 项目接入 Flutter Module

      随着 Flutter 的逐渐发展与完善,与 Native 结合使用的场景越来越多;小菜今天尝试将一个历史的 Android Native 项目接入 Flutter Module

AndroidX

      Flutter 的发展很迅速,大部分插件均适配 AndroidX,为了今后开发的便利性,小菜优先由如下版本升级适配 AndroidX


minSdkVersion 17targetSdkVersion 26
compileSdkVersion 28buildToolsVersion "28.0.3"
复制代码


      小菜以前尝试过 Flutter 升级适配 AndroidXAndroid 的处理类似,小菜以实际项目尝试适配;

1. 添加 AndroidX 配置

      在 android/gradle.properties 文件中添加如下配置:


android.useAndroidX=trueandroid.enableJetifier=true
复制代码
2. Migrate to AndroidX

      小菜通过 Android Studio 中的 Migrate to AndroidX 来配合升级(纯手动升级需要修改巨多的文件),选择本工程 -> Refactor -> Migrate to Androidx;但小菜当前 Gradle 版本是 3.0.0,此时提示 Gradle 需 >= 3.2.0,故小菜需要先升级 Gradle


3. Gradle 升级

      升级 android/build.gradle 文件中 Gradle 版本;此时 Sync 同步时会由如下两个提示;


classpath 'com.android.tools.build:gradle:3.2.0'
复制代码


3.1 compile 已经不建议使用,小菜把各个 Modulecompile 替换为 api / implementation


Configuration 'compile' is obsolete and has been replaced with 'implementation' and 'api'.It will be removed at the end of 2018. For more information see: http://d.android.com/r/tools/update-dependency-configurations.html
复制代码



3.2 小菜的项目中在之前通过 retrolambda 支持 Java8,在 Gradle > 3.0.0 之后默认支持 Java8,小菜将引入去掉即可;


One of the plugins you are using supports Java 8 language features. To try the support built into the Android plugin, remove the following from your build.gradle:    apply plugin: 'me.tatarka.retrolambda'To learn more, go to https://d.android.com/r/tools/java-8-support-message.html
复制代码


4. 重复第二步骤,Migrate to AndroidX

      注意要选择底部 Do Refactor,会帮我们节省巨大的工作量,只需要个别的文件引入或 xml 需要更改,否则需要我们手动修改大量的文件引入等;




5. Sync 同步打包检验

      若有个别 xml 文件需要调整,按照提示微调即可;debug / release 均需要打包检验;到此升级适配 AndroidX 工作基本完成;

Flutter Module

      小菜之前也尝试过 Android 原生集成 Flutter Module,小菜组内已有相关的 Flutter 工程,因此不再新建,集成方法很简单;

1. setting.gradle 中引入 Flutter Module 路径
setBinding(new Binding([gradle: this]))evaluate(new File(        '/Users/user/Documents/workspace/flutter_module02/.android/include_flutter.groovy'))
复制代码
2. app/build.project 中引入 Flutter 依赖
implementation project(':flutter')
复制代码
3. Sync 同步后检验

      小菜以前整理过 FlutterAndroid 原生交互,但为了验证方便小菜仅提供一个 FlutterActivity 供页面跳转即可;


public class FlutterMainActivity extends FlutterActivity {    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);    }}
复制代码


      小菜未使用 FlutterApplication,此时提示如下问题;


Caused by: java.lang.IllegalStateException: ensureInitializationComplete must be called after startInitialization    at io.flutter.embedding.engine.loader.FlutterLoader.ensureInitializationComplete(FlutterLoader.java:153)    at io.flutter.view.FlutterMain.ensureInitializationComplete(FlutterMain.java:80)    at io.flutter.app.FlutterActivityDelegate.onCreate(FlutterActivityDelegate.java:144)    at io.flutter.app.FlutterActivity.onCreate(FlutterActivity.java:89)    at com.test.FlutterMainActivity.onCreate(FlutterMainActivity.java:13)    at android.app.Activity.performCreate(Activity.java:6367)    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1110)    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2397)
复制代码



      在 FlutterMainActivity 中提前初始化后,又提示新的问题;


protected void onCreate(@Nullable Bundle savedInstanceState) {    FlutterMain.startInitialization(this);    super.onCreate(savedInstanceState);}
UncaughtException detected: java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.test-2/base.apk", zip file "/data/app/com.test-2/split_lib_dependencies_apk.apk", zip file "/data/app/com.test-2/split_lib_slice_0_apk.apk", zip file "/data/app/com.test-2/split_lib_slice_1_apk.apk"],nativeLibraryDirectories=[/data/app/com.test-2/lib/arm, /data/app/com.test-2/base.apk!/lib/armeabi, /data/app/com.test-2/split_lib_dependencies_apk.apk!/lib/armeabi, .../split_lib_slice_8_apk.apk!/lib/armeabi, /data/app/com.test-2/split_lib_slice_9_apk.apk!/lib/armeabi, /vendor/lib, /system/lib]]] couldn't find "libflutter.so" at java.lang.Runtime.loadLibrary(Runtime.java:379) at java.lang.System.loadLibrary(System.java:1086) at io.flutter.embedding.engine.loader.FlutterLoader.startInitialization(FlutterLoader.java:122) at io.flutter.embedding.engine.loader.FlutterLoader.startInitialization(FlutterLoader.java:93) at io.flutter.view.FlutterMain.startInitialization(FlutterMain.java:45) at com.test.FlutterMainActivity.onCreate(FlutterMainActivity.java:14)
复制代码


      小菜查询后发现目前项目 NDK 只支持 armeabi 架构,而 Flutter 支持的时 armeabi-v7a,加入之后检验;若项目有特殊要求 NDK 必须是 armeabi 时,可考虑将 armeabi-v7a 的 flutter.so 拷贝到项目中;


ndk {    abiFilters "armeabi", "armeabi-v7a", "x86"}
复制代码



      

小扩展

      小菜在适配 AndroidX 过程中还遇到如下问题,并非所有项目涉及,记录仅供参考;

Q1:All flavors must now belong to a named flavor dimension.

      小菜升级 Gradle 之后进行多渠道打包时会提示如下错误;


FAILURE: Build failed with an exception.* What went wrong:A problem occurred configuring project ':app'.> All flavors must now belong to a named flavor dimension. Learn more at https://d.android.com/r/tools/flavorDimensions-missing-error-message.html* Try:Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.* Get more help at https://help.gradle.orgBUILD FAILED in 0s
复制代码
A1:

      Gradle > 3.0 时多渠道打包需要指定一种 flavor dimensions;其中建议不要直接使用 main 的名称,否则容易出现新的重复键问题;com.android.build.gradle.internal.api.artifact.BuildableArtifactImpl


// 修改前productFlavors {  test1 {}  test2 {}  main {}}// 修改后flavorDimensions "main"productFlavors {  test1 { dimension "main" }  test2 { dimension "main" }  main0 { dimension "main" }}
复制代码
Q2:com.android.builder.dexing.DexArchiveBuilderException

      小菜在运行过程中还提示 DexArchiveBuilderException 错误;


com.android.builder.dexing.DexArchiveBuilderException
复制代码
A2:

      小菜查阅是未指定 Java8 的问题,添加指定 1.8 即可;


compileOptions {    sourceCompatibility 1.8    targetCompatibility 1.8}
复制代码
Q3:Unable to find method '...getOutputs()Ljava/util/List'
Error:Unable to find method 'com.android.build.gradle.api.BaseVariant.getOutputs()Ljava/util/List;'.Possible causes for this unexpected error include:<ul><li>Gradle's dependency cache may be corrupt (this sometimes occurs after a network connection timeout.)<a href="syncProject">Re-download dependencies and sync project (requires network)</a></li><li>The state of a Gradle build process (daemon) may be corrupt. Stopping all Gradle daemons may solve this problem.
复制代码
A3:

      小菜几经查证后发现是 ButterKinfe 版本较低,因此升级至支持 AndroidX10.2.1 的最新版本即可;注意,此时需要 Java8 环境;


dependencies {  implementation 'com.jakewharton:butterknife:10.2.1'  annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1'}
复制代码




      至此,小菜的历史项目升级适配 AndroidX 并接入 Flutter Module 基本完成,下一步是两者之间的交互;升级适配是一个艰难复杂的过程,可能会有很多意想不到的问题,希望可以沉下心来慢慢解决;如有问题请多多指导!


来源: 阿策小和尚

发布于: 3 小时前阅读数: 3
用户头像

还未添加个人签名 2021.05.13 加入

Android / Flutter 小菜鸟~

评论

发布
暂无评论
【Flutter 专题】77 图解历史 Android Native 项目接入 Flutter Module