前言

最近公司的项目用Flutter技能栈比较多,有些需求可能还需求一些Android原生的支撑,所以我做了一些Android原生混合Flutter开发的测验,参阅了一些文章,也遇到了一些问题,这儿把总结的经历共享出来。

本文是针对 Android 项目增加 Flutter 模块的状况编写的。

开发环境

  • PC with Win10 20H2
  • Android Studio Arctic Fox | 2020.3.1 Patch 2(试过小松鼠版别,太不喜欢了,电鳗就更没去测验)
  • AGP 7.0.2

创立一个Android项目

直接贴图带过了哈,这步应该都熟练的吧

Android 原生混合 Flutter 开发初体验之一

创立一个Flutter模块

这儿就有区别了,较新版的AS中供给直接创立Flutter模块的模板,可是我的北极狐版别没有,因此这儿演示两种方法:

AS模板创立

在你的当前项目中,运用AS菜单中的File > New > New Module… 创立一个新的Flutter模块,或许挑选一个此前就已准备好的Flutter模块。

Android 原生混合 Flutter 开发初体验之一

假如你挑选创立一个新的模块,你能够运用导游来协助你设置模块的称号,模块寄存的位置之类的装备项。

Android 原生混合 Flutter 开发初体验之一

  • 因为我这儿还是北极狐版的AS,所以我并未实践官方供给的模板创立方法,依照官方的说法,它会主动帮你装备好依靠联系,但我也不确定会不会遇到问题,没有最好,有的话应该也都和手动创立的方法差不多。

手动创立Flutter模块

Terminal执行下方指令

```
flutter create -t module --org com.randalldev fluttermodule
```

然后官方供给了两种方法增加依靠联系:

  1. AAR依靠模式

    AAR模式有个好处便是团队中的其他成员不需求安装Flutter SDK,最少只需求一个人输出AAR即可。

    可是我个人不喜欢这种方法,我更倾向于git submodule的项目管理方法,而且安装Flutter SDK的成本真实算不上高,因此,这种方法,我按下不表。

  2. 模块代码依靠模式

    这种方法保证了一步完成Android项目和Flutter模块的编译。这种方法关于你的开发一起触及两个部分而且快速迭代很便利,但这需求团队的每个人成员都安装Flutter SDK来保证顺畅编译这个混合app

    在主项意图settings.gradle中将Flutter模块作为子项目引进。

    // Include the host app project.
     include ':app'                                                // 默许已有的装备
     setBinding(new Binding([gradle: this]))                                // 新增
     evaluate(new File(                                                     // 新增
       settingsDir.parentFile,                                              // 新增
       "${rootProject.name}/fluttermodule/.android/include_flutter.groovy"  // 新增
     ))                                                                     // 新增
    

    此刻AS会提示你gradle装备改变了,需求重新sync,别急,先别点!

    假定fluttermodule是和app目录同层级的。

    appbuild.gradle中增加flutter模块的依靠

     dependencies {
       implementation project(':flutter')
     }
    

    官方的指南就到此为止了,与此一起,坑也来了/doge

排雷

此刻当你点了sync会呈现如下报错

* What went wrong:
A problem occurred evaluating script.
> Failed to apply plugin class 'FlutterPlugin'.
   > Build was configured to prefer settings repositories over project repositories but repository 'maven' was added by plugin class 'FlutterPlugin'

projectsetting.gradle

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        jcenter() // Warning: this repository is going to shut down soon
    }
}

改为

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.PREFER_PROJECT)
    repositories {
        google()
        mavenCentral()
        jcenter() // Warning: this repository is going to shut down soon
    }
}

此刻当你点了sync会呈现如下报错

A problem occurred evaluating project ':app'.
> Project with path ':fluttermodule' could not be found in project ':app'.

projectsetting.gradle的末尾增加

include ':fluttermodule'

此刻当你点了sync编译大概率能成功,可是会有很严重的正告

Failed to resolve: androidx.core:core-ktx:1.9.0
Add Google Maven repository and sync project
Show in Project Structure dialog
Affected Modules: app

projectbuild.gradle

task clean(type: Delete) {
    delete rootProject.buildDir
}

上方增加

allprojects {
    repositories {
        google()
        mavenCentral()
        maven { url 'https://jitpack.io' }
    }
}

至此,大体上一个混合的Android原生+Flutter项意图开始构建就完成了。

页面跳转

Android原生打开Flutter页面

默许的跳转方法会呈现明显的白屏,体验上很欠好,这儿直接给出优化后的方法

运用FlutterEngine缓存并复用

  1. appAndroidManifest.xml中注册FlutterActivity

    <activity
        android:name="io.flutter.embedding.android.FlutterActivity"
        android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
        android:hardwareAccelerated="true"
        android:theme="@style/Theme.HybridFlutter"
        android:windowSoftInputMode="adjustResize" >
    </activity>
    
  2. app中创立一个App.kt承继Application并在AndroidManifest.xml中装备给application节点的name特点

    class App : Application() {
        
    }
    
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.randalldev.hybridflutter">
        <application
            android:name=".App"
            
    </manifest>
    
  3. App.kt中准备好FlutterEngine

    1. 创立FlutterEngine实例

          private val flutterEngine by lazy {
              FlutterEngine(this).apply {
                  dartExecutor.executeDartEntrypoint(DartExecutor.DartEntrypoint.createDefault())
              }
          }
      
    2. 重写onCreate()并将实例存储FlutterEngineCache

      override fun onCreate() {
          super.onCreate()
          FlutterEngineCache.getInstance().put("your_engine_id", flutterEngine)
      }
      
    3. 重写onTerminate()并将实例毁掉

      override fun onTerminate() {
          super.onTerminate()
          flutterEngine.destroy()
      }
      
    4. 在业务需求的当地运用FlutterEngine中的Intent实例进行跳转

          findViewById<TextView>(R.id.textView).setOnClickListener {
              startActivity(FlutterActivity.withCachedEngine("your_engine_id").build(this))
          }
      
    5. 挑选app进行run

      Android 原生混合 Flutter 开发初体验之一

    6. 假如遇到如下Java版别问题,请进行如下装备改变

      A problem occurred evaluating project ':flutter'.
      > Failed to apply plugin 'com.android.internal.library'.
         > Android Gradle plugin requires Java 11 to run. You are currently using Java 1.8.
           You can try some of the following options:
             - changing the IDE settings.
             - changing the JAVA_HOME environment variable.
             - changing `org.gradle.java.home` in `gradle.properties`.
      
      1. 挑选 Project Structure > SDK location > Gradle Settings 设置Gradle JDK11

        Android 原生混合 Flutter 开发初体验之一

        Android 原生混合 Flutter 开发初体验之一

      2. ./gradle.properties中增加上文中对应的java.home途径

        # replace with your own jdk11 or above
        org.gradle.java.home=C\:\\Softwares\\Google\\Android\\Android_Studio\\jre
        
      3. sync后应该就能够顺畅的run

参阅文章

  • Integrate a Flutter module into your Android project
  • Android与Flutter混合开发
  • android混合flutter