美文网首页
Android 原生混合 Flutter 开发初体验之一

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

作者: _Jun | 来源:发表于2023-01-15 10:54 被阅读0次

    前言

    最近公司的项目用Flutter技术栈比较多,有些需求可能还需要一些Android原生的支持,所以我做了一些Android原生混合Flutter开发的尝试,参考了一些文章,也遇到了一些问题,这里把总结的经验分享出来。

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

    开发环境

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

    创建一个Android项目

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

    创建一个Flutter模块

    这里就有区别了,较新版的AS中提供直接创建Flutter模块的模板,但是我的北极狐版本没有,因此这里演示两种方式:

    AS模板创建

    在你的当前项目中,使用AS菜单中的 File > New > New Module… 创建一个新的Flutter模块,或者选择一个此前就已准备好的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,                                              // 新增
         '${root_project}/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

    1. 如果遇到如下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
    1. ./gradle.properties中添加上文中对应的java.home路径
    # replace with your own jdk11 or above
               org.gradle.java.home=C\:\\Softwares\\Google\\Android\\Android_Studio\\jre
    
    1. sync后应该就可以顺利的run

    参考文章

    作者:Randall_Xia
    链接:https://juejin.cn/post/7187979205215748156

    相关文章

      网友评论

          本文标题:Android 原生混合 Flutter 开发初体验之一

          本文链接:https://www.haomeiwen.com/subject/rgqacdtx.html