美文网首页DevSupport
Flutter之Gradle配置

Flutter之Gradle配置

作者: gczxbb | 来源:发表于2019-06-29 16:21 被阅读0次

    一、引入flutter.gradle文件

    基于flutter1.9.1版本。
    Flutter项目android工程app主模块,引入flutter.gradle配置文件,该文件在flutter sdk的flutter/packages/flutter_tools/gradle/目录下,目的是在普通android工程的编译打包流程中插入一些Flutter任务。

    apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
    

    app主模块,当Gradle运行到apply from时,进入flutter.gradle执行,代码流程。

    apply from引入flutter.gradle的代码流程

    在flutter.gradle文件,首先执行buildscript代码块,然后顺序执行,代码结构。

    flutter.gradle文件概况

    定义一个FlutterPlugin插件,实现接口Plugin<Project>的apply方法,Gradle运行到apply plugin: FlutterPlugin语句时,去执行apply方法(插入任务),执行结束回到app主模块,继续主模块Gradle文件后面的代码。
    FlutterTask任务类、FlutterPluginTask任务类。

    引入flutter.gradle的配置文件仅执行buildscript代码块和FlutterPlugin插件的apply方法,目的是插入Flutter任务。


    二、插件

    定义FlutterPlugin插件,实现接口Plugin<Project>,apply方法。

    @Override
    void apply(Project project) {
    }
    

    Project代表android工程的app模块,project.getName()是app。

    project.afterEvaluate this.&addFlutterTasks
    

    afterEvaluate,当apply()方法结束,project(app模块)的Gradle完成,再添加Flutter任务,调用addFlutterTasks()方法。

    String flutterRootPath = resolveProperty(project, "flutter.sdk", System.env.FLUTTER_ROOT)
    

    查找父目录下的local.properties文件,即(工程根目录),获取flutter.sdk路径和bin目录下可执行文件。

    String flutterExecutableName = Os.isFamily(Os.FAMILY_WINDOWS) ? "flutter.bat" : "flutter"
    flutterExecutable = Paths.get(flutterRoot.absolutePath, "bin", flutterExecutableName).toFile();
    

    根据不同平台去加载可执行文件。

    # basePlatform目标平台默认:android-arm64
    String basePlatformArch = getBasePlatform(project)
    
    Path baseEnginePath = Paths.get(flutterRoot.absolutePath, "bin", "cache", "artifacts", "engine")
    File debugJar = baseEnginePath.resolve("${basePlatformArch}").resolve("flutter.jar").toFile()
    baseJar["debug"] = debugJar
    
    baseJar["profile"] = baseEnginePath.resolve("${basePlatformArch}-profile").resolve("flutter.jar").toFile()
    baseJar["release"] = baseEnginePath.resolve("${basePlatformArch}-release").resolve("flutter.jar").toFile()
    

    从sdk的/bin/cache/artifacts/engine/路径,创建flutter.jar文件的Flie,三种构建模式debug,profile和release,从android-arm64-xxx对应目录加载。

    project.android.buildTypes.each {
        def buildMode = buildModeFor(it)
        println "each buildTypes 构建类型: $buildMode 添加flutter.jar依赖"
        addApiDependencies(project, it.name, project.files {
            baseJar[buildMode]
        })
    }
    

    遍历构建模式,通过project.dependencies.add()方法,添加android主模块对flutter.jar的依赖,project是android工程的app模块。

    if (project.getConfigurations().findByName("api")) {
        configuration = "${variantName}Api";
    } else {
        configuration = "${variantName}Compile";
    }
    project.dependencies.add(configuration, dependency, config)
    

    构建类型XxxApi,依赖文件。


    三、任务

    插件apply()完成,afterEvaluate设置addFlutterTasks()任务添加方法执行。

    private void addFlutterTasks(Project project) {
    }
    

    通过project.tasks.create()方法添加。

    ## 目标平台:[android-arm, android-arm64]
    def targetPlatforms = getTargetPlatforms(project)
    

    默认平台是arm和arm64。

    1,编译任务
    FlutterTask compileTask = project.tasks.create(name: taskName, type: FlutterTask) {
    }
    

    任务名:compileFlutterDebug构建模式+平台,类型是FlutterTask类,自定义任务类。

    compileFlutterBuildXxxArm,compileFlutterBuildXxxArm64
    构建模式:Debug,Profile,Release
    abi平台:Arm(32)和Arm64

    编译任务和执行产物

    addFlutterTasks方法仅将任务添加到Gradle的构建流程中,运行在编译过程中触发。

    编译过程中任务执行

    FlutterTask类build方法,父类DefaultTask的buildBundle()方法。

    @TaskAction
    void build() {
        buildBundle()
    }
    

    编译任务生成Dart产物build目录:intermediates/flutter/xxx/平台/。在平台目录下,产物debug和release模式不同,
    debug模式:flutter_assets目录下kernel_blob.bin,vm_snapshot_data,isolate_snapshot_data。
    releass模式:flutter_assets目录+app.so。

    2,lib任务
    Task packFlutterSnapshotsAndLibsTask = project.tasks.create(name: 
        "packLibs${FLUTTER_BUILD_PREFIX}${variant.name.capitalize()}", type: Jar) {
    }
    

    任务名:packLibsflutterBuild构建模式,类型是Jar类,Gradle内置任务类,将sdk中对应平台libflutter.so文件写入libs.jar压缩包。

    packLibsflutterBuildXxx,依赖对应编译任务
    构建模式:Debug,Profile,Release
    abi平台:依赖编译任务生成的目标平台

    debug模式,增加两个平台。

    if (flutterBuildMode == 'debug') {
        libFlutterPlatforms.add('android-x86')
        libFlutterPlatforms.add('android-x64')
    }
    

    在build/intermediates/flutter/xxx目录,定义一个libs.jar文件,将sdk的engine平台flutter.jar中lib目录下的so文件(lib/**)复制到压缩包libs.jar,当debug模式,多复制x86和x64平台的libflutter.so文件。其他模式,复制android-arm-xxx(32位)目录中的文件。

    debug模式lib任务

    将intermediates/flutter/release/android-arm和64的so文件(app.so),release模式编译过程,Dart产物包括so文件,重命名libapp.so,拷贝到libs.jar压缩包文件。

    // 包含so产物的intermediates/flutter/平台/,release和profile
    compileTasks.each { compileTask ->
        from(compileTask.intermediateDir) {
            include '*.so'
            rename { String filename ->
                println "rename:"+compileTask.intermediateDir
                return "lib/${compileTask.abi}/lib${filename}"
            }
        }
    }
    
    release模式libs.jar文件查看
    3,拷贝任务
    Task copyFlutterAssetsTask = project.tasks.create(name: 
        "copyFlutterAssets${variant.name.capitalize()}", type: Copy) {
    }
    

    任务名:copyFlutterAssets构建模式,类型是Copy类,Gradle内置任务类,

    copyFlutterAssetsXxx,依赖对应编译任务和packLibsflutterBuild任务
    构建类模式:Debug,Profile,Release
    abi平台:依赖编译任务生成的目标平台
    依赖cleanMergeXxxAssets,mergeXxxAssets

    # clean动作先执行
    variant.mergeAssets.mustRunAfter("clean${variant.mergeAssets.name.capitalize()}")
    

    拷贝是从intermediates的flutter目录到merged_assets目录下。

    /build/intermediates/merged_assets/release/mergeReleaseAssets/out
    

    拷贝内容是flutter_assets文件夹目录下/*。

    addApiDependencies(project, variant.name, project.files {
        packFlutterSnapshotsAndLibsTask
    })
    

    依赖packLibsflutterBuild任务。

    拷贝任务
    ## 运行拷贝任务
    > Task :app:cleanMergeDebugAssets UP-TO-DATE
    > Task :app:compileFlutterBuildDebugArm
    > Task :app:compileFlutterBuildDebugArm64
    > Task :app:mergeDebugShaders
    > Task :app:compileDebugShaders
    > Task :app:generateDebugAssets
    > Task :app:packLibsflutterBuildDebug UP-TO-DATE
    > Task :app:mergeDebugAssets
    > Task :app:copyFlutterAssetsDebug
    8 actionable tasks: 6 executed, 2 up-to-date
    11:42:04: Task execution finished 'copyFlutterAssetsDebug'.
    
    4,构建顺序

    Debug模式,Gradle顺序。

    Debug模式Run tasks

    四、Dart编译命令

    BaseFlutterTask基类的buildBundle()方法,调用Flutter构建命令,生成Futter产物。
    sourceDir目录,即根目录中,包含lib/main.dart文件的目录,添加任务时,构建目录默认是lib/main.dart,通过project.exec {..}方法,执行命令。

    void buildBundle() {
        intermediateDir.mkdirs()
        if (buildMode == "profile" || buildMode == "release") {
            project.exec {
                executable flutterExecutable.absolutePath
                workingDir sourceDir
                args "build", "aot"
                args "--target", targetPath
                args "--output-dir", "${intermediateDir}"
                ...//args参数
            }
        }
        project.exec {
            executable flutterExecutable.absolutePath
            workingDir sourceDir
            args "build", "bundle"
            args "--target", targetPath
            args "--target-platform", "${targetPlatform}"
            ...//args参数
            args "--asset-dir", "${intermediateDir}/flutter_assets"
            if (buildMode == "debug") {
                args "--debug"
            }
            if (buildMode == "profile") {
                args "--profile"
            }
            if (buildMode == "release") {
                args "--release"
            }
        }
    }
    

    release和profile构建模式,两次命令,第一个project.exec。

    flutter build aot --suppress-analytics --quiet --target lib/main.dart --target-platform android-arm --output-dir build/app/intermediates/flutter/release --release

    输出目录是intermediates/flutter/release/平台/,产物是app.so文件,不支持debug构建模式。
    所有构建模式,第二个project.exec。

    flutter build bundle --suppress-analytics --target lib/main.dart --precompiled --asset-dir build/app/intermediates/flutter/release/flutter_assets --release

    build bundle,产物是flutter_assets目录。


    任重而道远

    相关文章

      网友评论

        本文标题:Flutter之Gradle配置

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