Android Flutter混合开发问题总结(二)

2,073 阅读2分钟

Android Flutter混合开发问题总结
Android Flutter混合开发问题总结(二)

之前介绍过一些Android Flutter混合开发的注意点以及一些基本知识, 接下来介绍一下实际开发过程中,目前一定会遇到的两个坑。
在Flutter开发过程中,如果是以module的形式进行依赖,是无法进行android原生部分的调试的,无法进行attach debug to android process操作; 为了解决这一问题,我们需要考虑使用aar的方式,以library的形式进行依赖,但是讲flutter打包成library的时候,如果使用第三方框架,会导致第三方框架无法打包进入aar,因此我们需要来解决这一问题。

混合开发的依赖方式

打包成独立aar

打包aar很简单,进入flutter工程,然后进入.android目录,输入指令: 打debug的aar包:

./gradlew flutter:assembleDebug

打debug的release包:

./gradlew flutter:assembleRelease

打好的包在 flutter module/.android/Flutter/build/outputs/aar

aar的包打好后可以直接复制到Android工程去依赖即可。
但是如果使用第三方框架会导致第三方框架的无法打入aar,我们可以使用fat-aar-android来解决这一问题:
在flutter工程的build.gradle加入:

    classpath 'com.kezong:fat-aar:1.2.7'

在Flutter的build.gradle加入如下配置:

apply plugin: 'com.kezong.fat-aar'

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')
    }
}

在Android工程下的settings.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
}

这样打包出来的aar就包含了第三方的aar。

Flutter工程作为module依赖

以module方式依赖之前介绍过,可以直接查看文章Android Flutter混合开发问题总结

混合开发的调试填坑

Flutter android混合工程的依赖方式写到这里,但是实际开发中会有一个无法避免的坑,就是flutter工程无法调试android代码,如下图所示例:
原生Android项目:

image

Flutter项目:

image

为了解决这一问题,我想到的解决方法就输使用aar模式来进行原生Android的开发,用依赖module的方式来进行flutter工程的开发。

开发模式参数配置

我们可以通过一个变量来控制当前开发环境是Android还是Flutter,效果如下:

image

通过gradle.properties的一个值来控制进行flutter开发还是Android部分开发。

具体操作如下:
1、讲Flutter部分打包成aar放入libs文件夹下
2、Android工程的project的build.gradle加入如下依赖:

    classpath 'com.kezong:fat-aar:1.2.7'

3、app的build.gradle加入如下配置:

dependencies{
    def properties = new Properties()
    def pluginsFile = new File("${rootDir.getAbsolutePath()}/gradle.properties")
    if (pluginsFile.exists()) {
        pluginsFile.withReader('UTF-8') { reader -> properties.load(reader) }
    }
    def isFlutterDebug = properties.getProperty('isFlutterDebug').toBoolean()
    if (isFlutterDebug) {
        implementation project(':flutter')
    } else {
        implementation files('libs/flutter-release.aar')
//        implementation files('libs/flutter-debug.aar')
    }
}

4、gradle.properties加入如下参数来控制调试方式:

## 是否在线调试flutter代码
isFlutterDebug=false

5、settings.gradle修改为如下配置:
xxx_flutter为自己flutter工程的名字。

def properties = new Properties()
def rootProjectFile = new File(settingsDir.getPath()).getAbsolutePath()
def propertiesFile = new File("${rootProjectFile}/gradle.properties")
if (propertiesFile.exists()) {
    propertiesFile.withReader('UTF-8') { reader -> properties.load(reader) }
}
def isFlutterDebug = properties.getProperty("isFlutterDebug").toBoolean()
if (isFlutterDebug) {
    setBinding(new Binding([gradle: this]))
    evaluate(new File(settingsDir.parentFile,
            'xxx_flutter/.android/include_flutter.groovy'
    ))
    include ':xxx_flutter'
    project(':xxx_flutter').projectDir = new File('../xxx_flutter')
}else {
    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
    }
}

这样配置完成后就可以由自己来控制到底进行Flutter开发还是Android开发。

总结

Flutter开发的坑还有不少,以此记录方便大家来解决问题。