Flutter圈子Android开发经验谈Android技术知识

Android原生以AAR形式集成Flutter混合开发

2020-04-12  本文已影响0人  闲庭

开发集成环境
[✓] Flutter (Channel unknown, v1.12.13+hotfix.8, on Mac OS X 10.14.6 18G103, locale zh-Hans-CN)

谈到目前跨平台框架的应用,无非两种,一种使用纯跨平台技术开发的项目,一种是与原生进行混编的项目,当然这里所讲的是后者,后者相对前者稍微复杂些,而且目前大多数都是在原有项目中逐步插入跨平台技术,当然一些新项目除外。
一、简述Flutter集成到Android原生项目
二、Android原生以AAR形式集成Flutter项目
三、Flutter与原生的消息通信
四、Flutter中如何使用原生控件/组件
五、Flutter升级及开发中遇到的问题汇总

其实在Flutter官网上 Add Flutter to existing app 就提供了两种将Flutter引入的方式。

这里主要介绍方式一通过以Android Archive (AAR)形式引入Flutter依赖,步骤如下:

  1. .android目录下的build.gradle目录下添加依赖:

    buildscript {
        repositories {
            google()
            jcenter()
        }
    
        dependencies {
            classpath 'com.android.tools.build:gradle:3.5.0'
            classpath "com.kezong:fat-aar:1.2.8"  //新增这行 
        }
    }
    
    allprojects {
        repositories {
            google()
            jcenter()
            ...
        }
    }
    
    task clean(type: Delete) {
        delete rootProject.buildDir
    }
    
  2. .android/settings.gradle 文件中添加如下代码:

    // Generated file. Do not edit.
    include ':app'
    
    rootProject.name = 'android_generated'
    setBinding(new Binding([gradle: this]))
    evaluate(new File(settingsDir, 'include_flutter.groovy'))
    
    //新增以下部分
    def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
    
    def plugins = new Properties()
    def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
    if (pluginsFile.exists()) {
        pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
    }
    
    plugins.each { name, path ->
        def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
        include ":$name"
        project(":$name").projectDir = pluginDirectory
    }
    
  3. .android/Flutter/build.gradle 文件中添加如下代码:

    dependencies {
        testImplementation 'junit:junit:4.12'
        //新增以下部分
        def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
        def plugins = new Properties()
        def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
        if (pluginsFile.exists()) {
            pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
        }
        plugins.each { name, _ ->
            println name
            embed project(path: ":$name", configuration: 'default')
        }
    }
    
    apply plugin: "com.kezong.fat-aar"
    apply plugin: 'maven'
    
    final def localMaven = true // true:发布到本地maven仓库, false: 发布到maven私服
    
    final def artGroupId = "com.cc.flutter"
    final def artVersion = "1.0.1"
    final def artifactId = "test-flutter"
    
    final def mavenUrl = "http://10.181.xx.xx:8083/repository/repo/"
    final def mavenAccountName = "admin"
    final def mavenAccountPwd = "admin123"
    final def localRepo = "../../repo-local" //在根目录创建repo-local文件夹
    
    uploadArchives {
        repositories {
            mavenDeployer {
                println "==maven url: ${artGroupId}:${artifactId}:${artVersion}"
                println "==localMaven : ${localMaven}:${localRepo}"
                if(localMaven) {
                    repository(url: uri(localRepo))
                } else {
                    repository(url: mavenUrl) {
                        authentication(userName: mavenAccountName, password: mavenAccountPwd)
                    }
                }
    
                pom.groupId = artGroupId
                pom.artifactId = artifactId
                pom.version = artVersion
    
                pom.project {
                    licenses {
                        license {
                            name 'The Apache Software License, artVersion 2.0'
                            url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
                        }
                    }
                }
            }
        }
    }
    
  4. 在项目根目录下创建打包脚本aar.sh,内容如下:

    #!/bin/bash
    
    # 初始化记录项目pwd
    projectDir=`pwd`
    
    # step 1 clean
    echo 'clean old build'
    find . -depth -name "build" | xargs rm -rf
    cd ${projectDir} # 回到项目
    rm -rf .android/Flutter/build
    #flutter clean
    
    # step 2 package get
    echo 'packages get'
    cd ${projectDir} # 回到项目
    flutter packages get
    
    # step 3 build aar,生成aar,然后上传到对应maven仓库
    echo 'build aar'
    cd ${projectDir}
    flutter build apk
    if [ $? -eq 0 ]; then
        echo '打包成aar 成功!'
    else
        echo '打包成aar 失败!'
        exit 1
    fi
    
    cd ${projectDir}/.android
    ./gradlew flutter:uploadArchives
    
    if [ $? -eq 0 ]; then
        echo 'uploadArchives 成功!'
    else
        echo 'uploadArchives 失败!'
        exit 1
    fi
    
    echo '<<<<<<<<<<<<<<<<<<<<<<<<<< 打包成功,aar上传成功 >>>>>>>>>>>>>>>>>>>>>>>>>'
    echo "打包成功 : flutter-release.aar, 本地仓库:${projectDir}/repo-local"
    exit
    
  5. 在根目录下打开命令行,执行打包脚本即可:

    $ ./aar.sh
    

    打包成功后可自动将打包的aar上传至对应的maven仓库,此处放在本地仓库根目录下的repo-local文件夹下。

  6. 将对应仓库中的aar文件引入原生项目中

上述步骤即可对Flutter以AAR方式引入到原生Android中进行混合开发,后面会逐渐对打包流程进行优化,以下的优化迭代并不是最终方案(一步步来)。现在你可以进行创建一个demo然后集成到自己的项目中进行试手,体验以下Flutter。后期会逐步完善Dart语法相关笔记与Flutter相关笔记。


上述打包流程稍微有点繁琐,如果现有项目比较多,需要重复配置同样的信息,所以进行打包步骤优化通用配置:

  1. 在项目根目录下创建configs文件夹,里面分别创建dependencies_gradle_plugin.gradlesetting_gradle_plugin.gradleuploadArchives.gradle 三个文件

    • dependencies_gradle_plugin.gradle 文件内容如下:
      dependencies {
          def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
          def plugins = new Properties()
          def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
          if (pluginsFile.exists()) {
              pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
          }
          plugins.each { name, _ ->
              println name
              embed project(path: ":$name", configuration: 'default')
          }
      }
      
    • setting_gradle_plugin.gradle文件内容如下:
      def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
      
      def plugins = new Properties()
      def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
      if (pluginsFile.exists()) {
          pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
      }
      
      plugins.each { name, path ->
          def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
          include ":$name"
          project(":$name").projectDir = pluginDirectory
      }
      
    • uploadArchives.gradle 文件内容如下:
      apply plugin: 'maven'
      
      final def localMaven = true //true: 发布到本地maven仓库, false: 发布到maven私服
      
      final def artGroupId = "com.cc.flutter"
      final def artVersion = "1.0.1"
      final def artifactId = "test-flutter"
      
      final def mavenUrl = "http://10.181.xx.xx:8083/repository/repo/"
      final def mavenAccountName = "admin"
      final def mavenAccountPwd = "admin123"
      final def localRepo = "../../repo-local"
      
      uploadArchives {
          repositories {
              mavenDeployer {
                  println "==maven url: ${artGroupId}:${artifactId}:${artVersion}"
                  println "==localMaven : ${localMaven}:${localRepo}"
                  if(localMaven) {
                      repository(url: uri(localRepo))
                  } else {
                      repository(url: mavenUrl) {
                          authentication(userName: mavenAccountName, password: mavenAccountPwd)
                      }
                  }
      
                  pom.groupId = artGroupId
                  pom.artifactId = artifactId
                  pom.version = artVersion
      
                  pom.project {
                      licenses {
                          license {
                              name 'The Apache Software License, artVersion 2.0'
                              url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
                          }
                      }
                  }
              }
          }
      }
      
  2. .android目录下的build.gradle目录下添加依赖:
    classpath "com.kezong:fat-aar:1.2.8" //新增这行

  3. 在.android/settings.gradle文件中添加如下代码:

    apply from: "../configs/setting_gradle_plugin.gradle"
    
  4. 在.android/Flutter/build.gradle中添加如下代码:

    apply from: "../../configs/uploadArchives.gradle"
    ...
    //下面放在尾部
    apply plugin: "com.kezong.fat-aar"
    apply from: "../../configs/dependencies_gradle_plugin.gradle"
    

稍后的利用打包脚本执行打包上传相应仓库的步骤和引入到原生项目中的流程和上述一致。

上一篇下一篇

猜你喜欢

热点阅读