Flutter作为模块集成到Android项目中

1 我的环境

Flutter doctor 显示出来的我的本地环境

PS D:\code\git-repos\project\hsgay\dmga-hsgayapp> flutter doctor
Flutter assets will be downloaded from https://storage.flutter-io.cn. Make sure you trust this source!
Doctor summary (to see all details, run flutter doctor -v):
[!] Flutter (Channel unknown, 3.3.8, on Microsoft Windows [版本 10.0.19045.2965], locale zh-CN)
    ! Flutter version 3.3.8 on channel unknown at D:\data\flutter                              
    ! Upstream repository unknown                                                              
[!] Android toolchain - develop for Android devices (Android SDK version 31.0.0-rc1)                     
    X Android license status unknown.                                                                    
      Run `flutter doctor --android-licenses` to accept the SDK licenses.                                
      See https://flutter.dev/docs/get-started/install/windows#android-setup for more details.           
[] Chrome - develop for the web                                                                         
[X] Visual Studio - develop for Windows                                                                  
    X Visual Studio not installed; this is necessary for Windows development.                            
      Download at https://visualstudio.microsoft.com/downloads/.                                         
      Please install the "Desktop development with C++" workload, including all of its default components
[!] Android Studio (version 2021.3)                                                                      
    X Unable to determine bundled Java version.                                                          
[!] Android Studio (version 2022.2)                                                                      
    X Unable to find bundled Java version.                                                               
[] IntelliJ IDEA Ultimate Edition (version 2022.2)                                                      
[] IntelliJ IDEA Ultimate Edition (version 2022.3)                                                      
[] Connected device (4 available)                                                                       
[] HTTP Host Availability                                                                               

! Doctor found issues in 5 categories.

准备的2个工程:

  • dmga-hsgayapp (flutter工程)
  • dmga-hsgayapp-jz (android原生工程)

现在要把 dmga-hsgayapp 作为 module 集成到 dmga-hsgayapp-jz 中。

2 Flutter作为模块集成到Android中

参考官方文档:
https://docs.flutter.dev/add-to-app/android/project-setup

2.1 创建 Flutter Module

创建 Flutter Module 有2种方式,其一是官网上提到的直接新建一个 Flutter module

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

但是我的工程 dmga-hsgayapp 原本是一个 Flutter App ,现在再去新建一个 Flutter Module 还得拷贝代码,不便于维护。下面介绍另一种方式,将 Futter App 转换为 Flutter Module

  • pubspec.yaml 中添加如下代码
flutter:
	module:  
	  androidPackage: com.dm.pcbd  
	  androidX: true
  • 执行 pub get
flutter pub get
  • 再删除掉工程下的 android 目录
    上面执行完 flutter pub get 之后,会生成 .android.ios 目录,此时要把 Flutter App 中原本自带的 android 目录删除掉,否则无法作为 Flutter module

  • 删除 android 目录后的目录结构
    Flutter作为模块集成到Android项目中_第1张图片

2.2 Android工程设置 Java 11

Android 工程 dmga-hsgayapp-jz 中,设置 Java 11

app/build.gradle 文件中设置
Flutter作为模块集成到Android项目中_第2张图片

android{
	// ...省略其它内容
	compileOptions {  
	    sourceCompatibility 11  
	    targetCompatibility 11  
	}
}

2.3 将 Flutter 作为模块添加到 Android 工程

Flutter 支持2种方式集成到 Android 工程,分别是:

  • aar包方式
  • 源代码方式

aar包方式类似于 java 中打成 jar 包,源码方式则类似于 java 中的工程依赖。显然,aar 包适合在生产环境下使用,源码方式适合在开发环境下使用。

采用源码方式时,开发者需要在本地安装 Flutter SDK

2.3.1 采用 AAR 包方式集成到 Android 工程

Flutter 工程 dmga-hsgayapp 下执行命令直接构建 aar

flutter build aar

Flutter作为模块集成到Android项目中_第3张图片

这个命令会在本地 build 目录生成一个 repo ,结构像下面这样:

build/host/outputs/repo
└── com
    └── example
        └── my_flutter
            ├── flutter_release
            │   ├── 1.0
            │   │   ├── flutter_release-1.0.aar
            │   │   ├── flutter_release-1.0.aar.md5
            │   │   ├── flutter_release-1.0.aar.sha1
            │   │   ├── flutter_release-1.0.pom
            │   │   ├── flutter_release-1.0.pom.md5
            │   │   └── flutter_release-1.0.pom.sha1
            │   ├── maven-metadata.xml
            │   ├── maven-metadata.xml.md5
            │   └── maven-metadata.xml.sha1
            ├── flutter_profile
            │   ├── ...
            └── flutter_debug
                └── ...

再去 Android 工程 dmga-hsgayapp-jz 下的 app/build.gradle 文件中设置 repository 及依赖,如下所示:

android {
  // ...
}

repositories {
  maven {
    url 'some/path/my_flutter/build/host/outputs/repo'
    // This is relative to the location of the build.gradle file
    // if using a relative path.
  }
  maven {
    url 'https://storage.googleapis.com/download.flutter.io'
  }
}

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

这就集成完了,再就是在 Android 工程中通过 Flutter Engine 访问 Flutter 页面了。

2.3.2 采用源码依赖方式集成到 Android 工程

采用源码方式略有不同,不需要打 aar 包,适合开发环境,避免频繁打包。

具体需要修改 Android 工程 dmga-hsgayapp-jz 中的以下几个文件:

gradle.properties

distributionBase=GRADLE_USER_HOME  
distributionPath=wrapper/dists  
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip  
zipStoreBase=GRADLE_USER_HOME  
zipStorePath=wrapper/dists
gradle还是老老实实升级到 7.x , 6.x或更低版本在 java 11 这里过不了
gradle不要升级到 8.x ,目前 flutter 还不兼容 gradle 8.x ,当然未来可能会兼容

settings.gradle

// rootProject.name也可不指定
rootProject.name = "dmga-hsgayapp-jz"  

include ':app'  
  
setBinding(new Binding([gradle: this]))  

// 指定 flutter 工程dmga-hsgayapp 下的 .android/include_flutter.groovy 文件
evaluate(new File(  
        'D:\\code\\git-repos\\project\\hsgay\\dmga-hsgayapp\\.android\\include_flutter.groovy'  
))

build.gradle

buildscript {  
    ext.kotlin_version = '1.8.0'  
    repositories {  
        google()  
        mavenCentral()  
    }  

	// android gradle plugin 老老实实用 7.x 版本,不要用 4.x,这些问题折腾了几天
    dependencies {  
        classpath 'com.android.tools.build:gradle:7.4.2'  
    }  
}  
  
task clean(type: Delete) {  
    delete rootProject.buildDir  
}

app/build.gradle

dependencies{
	// 省略其它依赖...

	// 添加 :flutter 依赖,对应的就是 flutter 工程 dmga-hsgayapp
	implementation project(':flutter')
}

到这里,就配置完成了。下面就可以在 Android 工程中创建 Flutter Engine 访问 Flutter页面了

下面,再把过程中遇到的比较麻烦的问题记录一下。

问题1:无法应用 FlutterPlugin

参考文档: https://github.com/flutter/flutter/issues/101347

* Where:
Script 'D:\data\flutter\packages\flutter_tools\gradle\flutter.gradle' line: 1031

* What went wrong:
A problem occurred evaluating script.
> Failed to apply plugin class 'FlutterPlugin'.
   > Cannot run Project.afterEvaluate(Closure) when the project is already evaluated.

这个问题的根本原因出在 build.gradle 文件中有下面这几行代码

rootProject.buildDir = './build'  
subprojects {  
    project.buildDir = "${rootProject.buildDir}/${project.name}"  
}  
subprojects {  
    project.evaluationDependsOn(':app')  
}

这里相当于把 subproject 又依赖并编译了1次,而 flutter 源码依赖进来时就受到这个的影响了。

其实这里这么配置是因为我的 Android 工程中有引一个子工程,所以才这么配置,没想到影响到了 flutter 集成。

解决起来很简单,把这里给删除掉即可。

// rootProject.buildDir = './build'  
// subprojects {  
//     project.buildDir = "${rootProject.buildDir}/${project.name}"  
// }  
// subprojects {  
//     project.evaluationDependsOn(':app')  
// }

至于 Android工程 中的子工程怎么办,就采用 aar 方式依赖进来了,至少目前不需要调试子工程。

问题2:No signature of method: org.gradle.api.tasks.bundling.Jar.destinationDir

No signature of method: org.gradle.api.tasks.bundling.Jar.destinationDir() is applicable for argument types

参考文档: https://stackoverflow.com/questions/75294879/no-signature-of-method-org-gradle-api-tasks-bundling-jar-destinationdir

flutter 跟gradle 8.x 还不兼容,把gralde改成7.6版本就好了

3 关于作者

作者是一个热爱学习、开源、分享,传播正能量,头发还很多的程序员-。-
热烈欢迎大家关注、点赞、评论交流!

  • csdn: https://blog.csdn.net/u010920692
  • 掘金: https://juejin.cn/user/3237392838298663
  • 博客园: https://www.cnblogs.com/zhangzhxb/

你可能感兴趣的:(android,flutter)