Flutter之Gradle配置


一怠噪、引入flutter.gradle文件

基于flutter1.9.1版本区赵。
Flutter項目android工程app主模塊愉烙,引入flutter.gradle配置文件减牺,該文件在flutter sdk的flutter/packages/flutter_tools/gradle/目錄下页徐,目的是在普通android工程的編譯打包流程中插入一些Flutter任務(wù)苏潜。

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

app主模塊,當(dāng)Gradle運行到apply from時变勇,進入flutter.gradle執(zhí)行恤左,代碼流程。

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

在flutter.gradle文件搀绣,首先執(zhí)行buildscript代碼塊飞袋,然后順序執(zhí)行,代碼結(jié)構(gòu)链患。

flutter.gradle文件概況

定義一個FlutterPlugin插件巧鸭,實現(xiàn)接口Plugin<Project>的apply方法,Gradle運行到apply plugin: FlutterPlugin語句時麻捻,去執(zhí)行apply方法(插入任務(wù))纲仍,執(zhí)行結(jié)束回到app主模塊,繼續(xù)主模塊Gradle文件后面的代碼芯肤。
FlutterTask任務(wù)類、FlutterPluginTask任務(wù)類压鉴。

引入flutter.gradle的配置文件僅執(zhí)行buildscript代碼塊和FlutterPlugin插件的apply方法崖咨,目的是插入Flutter任務(wù)。


二油吭、插件

定義FlutterPlugin插件击蹲,實現(xiàn)接口Plugin<Project>,apply方法婉宰。

@Override
void apply(Project project) {
}

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

project.afterEvaluate this.&addFlutterTasks

afterEvaluate心包,當(dāng)apply()方法結(jié)束类咧,project(app模塊)的Gradle完成,再添加Flutter任務(wù)蟹腾,調(diào)用addFlutterTasks()方法痕惋。

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

查找父目錄下的local.properties文件,即(工程根目錄)娃殖,獲取flutter.sdk路徑和bin目錄下可執(zhí)行文件值戳。

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

根據(jù)不同平臺去加載可執(zhí)行文件。

# basePlatform目標(biāo)平臺默認: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/路徑炉爆,創(chuàng)建flutter.jar文件的Flie堕虹,三種構(gòu)建模式debug卧晓,profile和release,從android-arm64-xxx對應(yīng)目錄加載赴捞。

project.android.buildTypes.each {
    def buildMode = buildModeFor(it)
    println "each buildTypes 構(gòu)建類型: $buildMode 添加flutter.jar依賴"
    addApiDependencies(project, it.name, project.files {
        baseJar[buildMode]
    })
}

遍歷構(gòu)建模式逼裆,通過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)

構(gòu)建類型XxxApi,依賴文件昼钻。


三掸屡、任務(wù)

插件apply()完成,afterEvaluate設(shè)置addFlutterTasks()任務(wù)添加方法執(zhí)行然评。

private void addFlutterTasks(Project project) {
}

通過project.tasks.create()方法添加仅财。

## 目標(biāo)平臺:[android-arm, android-arm64]
def targetPlatforms = getTargetPlatforms(project)

默認平臺是arm和arm64。

1碗淌,編譯任務(wù)
FlutterTask compileTask = project.tasks.create(name: taskName, type: FlutterTask) {
}

任務(wù)名:compileFlutterDebug構(gòu)建模式+平臺盏求,類型是FlutterTask類,自定義任務(wù)類亿眠。

compileFlutterBuildXxxArm碎罚,compileFlutterBuildXxxArm64
構(gòu)建模式:Debug,Profile纳像,Release
abi平臺:Arm(32)和Arm64

編譯任務(wù)和執(zhí)行產(chǎn)物

addFlutterTasks方法僅將任務(wù)添加到Gradle的構(gòu)建流程中荆烈,運行在編譯過程中觸發(fā)。

編譯過程中任務(wù)執(zhí)行

FlutterTask類build方法竟趾,父類DefaultTask的buildBundle()方法憔购。

@TaskAction
void build() {
    buildBundle()
}

編譯任務(wù)生成Dart產(chǎn)物build目錄:intermediates/flutter/xxx/平臺/。在平臺目錄下岔帽,產(chǎn)物debug和release模式不同玫鸟,
debug模式:flutter_assets目錄下kernel_blob.bin,vm_snapshot_data犀勒,isolate_snapshot_data屎飘。
releass模式:flutter_assets目錄+app.so。

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

任務(wù)名:packLibsflutterBuild構(gòu)建模式枚碗,類型是Jar類,Gradle內(nèi)置任務(wù)類铸本,將sdk中對應(yīng)平臺libflutter.so文件寫入libs.jar壓縮包肮雨。

packLibsflutterBuildXxx,依賴對應(yīng)編譯任務(wù)
構(gòu)建模式:Debug箱玷,Profile怨规,Release
abi平臺:依賴編譯任務(wù)生成的目標(biāo)平臺

debug模式陌宿,增加兩個平臺。

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

在build/intermediates/flutter/xxx目錄波丰,定義一個libs.jar文件壳坪,將sdk的engine平臺flutter.jar中l(wèi)ib目錄下的so文件(lib/**)復(fù)制到壓縮包libs.jar,當(dāng)debug模式掰烟,多復(fù)制x86和x64平臺的libflutter.so文件爽蝴。其他模式,復(fù)制android-arm-xxx(32位)目錄中的文件纫骑。

debug模式lib任務(wù)

將intermediates/flutter/release/android-arm和64的so文件(app.so)蝎亚,release模式編譯過程,Dart產(chǎn)物包括so文件先馆,重命名libapp.so发框,拷貝到libs.jar壓縮包文件。

// 包含so產(chǎn)物的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梅惯,拷貝任務(wù)
Task copyFlutterAssetsTask = project.tasks.create(name: 
    "copyFlutterAssets${variant.name.capitalize()}", type: Copy) {
}

任務(wù)名:copyFlutterAssets構(gòu)建模式,類型是Copy類仿野,Gradle內(nèi)置任務(wù)類铣减,

copyFlutterAssetsXxx,依賴對應(yīng)編譯任務(wù)和packLibsflutterBuild任務(wù)
構(gòu)建類模式:Debug脚作,Profile葫哗,Release
abi平臺:依賴編譯任務(wù)生成的目標(biāo)平臺
依賴cleanMergeXxxAssets,mergeXxxAssets

# clean動作先執(zhí)行
variant.mergeAssets.mustRunAfter("clean${variant.mergeAssets.name.capitalize()}")

拷貝是從intermediates的flutter目錄到merged_assets目錄下鳖枕。

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

拷貝內(nèi)容是flutter_assets文件夾目錄下/*魄梯。

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

依賴packLibsflutterBuild任務(wù)桨螺。

拷貝任務(wù)
## 運行拷貝任務(wù)
> 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宾符,構(gòu)建順序

Debug模式,Gradle順序灭翔。

Debug模式Run tasks

四魏烫、Dart編譯命令

BaseFlutterTask基類的buildBundle()方法,調(diào)用Flutter構(gòu)建命令肝箱,生成Futter產(chǎn)物哄褒。
sourceDir目錄,即根目錄中煌张,包含lib/main.dart文件的目錄呐赡,添加任務(wù)時,構(gòu)建目錄默認是lib/main.dart骏融,通過project.exec {..}方法链嘀,執(zhí)行命令萌狂。

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參數(shù)
        }
    }
    project.exec {
        executable flutterExecutable.absolutePath
        workingDir sourceDir
        args "build", "bundle"
        args "--target", targetPath
        args "--target-platform", "${targetPlatform}"
        ...//args參數(shù)
        args "--asset-dir", "${intermediateDir}/flutter_assets"
        if (buildMode == "debug") {
            args "--debug"
        }
        if (buildMode == "profile") {
            args "--profile"
        }
        if (buildMode == "release") {
            args "--release"
        }
    }
}

release和profile構(gòu)建模式,兩次命令怀泊,第一個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/平臺/,產(chǎn)物是app.so文件霹琼,不支持debug構(gòu)建模式务傲。
所有構(gòu)建模式,第二個project.exec枣申。

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

build bundle售葡,產(chǎn)物是flutter_assets目錄。


任重而道遠

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末糯而,一起剝皮案震驚了整個濱河市天通,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌熄驼,老刑警劉巖像寒,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異瓜贾,居然都是意外死亡诺祸,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門祭芦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來筷笨,“玉大人,你說我怎么就攤上這事龟劲∥赶模” “怎么了?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵昌跌,是天一觀的道長仰禀。 經(jīng)常有香客問我,道長蚕愤,這世上最難降的妖魔是什么答恶? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮萍诱,結(jié)果婚禮上悬嗓,老公的妹妹穿的比我還像新娘。我一直安慰自己裕坊,他們只是感情好包竹,可當(dāng)我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般周瞎。 火紅的嫁衣襯著肌膚如雪悟狱。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天堰氓,我揣著相機與錄音挤渐,去河邊找鬼。 笑死双絮,一個胖子當(dāng)著我的面吹牛浴麻,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播囤攀,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼软免,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了焚挠?” 一聲冷哼從身側(cè)響起膏萧,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蝌衔,沒想到半個月后榛泛,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡噩斟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年曹锨,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片剃允。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡沛简,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出斥废,到底是詐尸還是另有隱情椒楣,我是刑警寧澤,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布牡肉,位于F島的核電站捧灰,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏荚板。R本人自食惡果不足惜凤壁,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一吩屹、第九天 我趴在偏房一處隱蔽的房頂上張望跪另。 院中可真熱鬧,春花似錦煤搜、人聲如沸免绿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嘲驾。三九已至淌哟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間辽故,已是汗流浹背徒仓。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留誊垢,地道東北人掉弛。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像喂走,于是被迫代替她去往敵國和親殃饿。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內(nèi)容