背景
開發(fā)過程中會(huì)有這樣一種需求:app需要從遠(yuǎn)程獲取部分前置資源(比如接口配置信息)替蛉。通常做法是打包前手動(dòng)內(nèi)置到assets中,但這種方式比較低效,今天我們就來討論一種自動(dòng)化的過程
自定義Gradle插件獲取遠(yuǎn)程資源并配置到sourceSets中
class PreloadAssetsPlugin : Plugin<Project> {
override fun apply(target: Project) {
// 判斷是否為主工程
if (target.plugins.hasPlugin("com.android.application")) {
val pathSeparator = File.separator
// 自定義asset目錄
val tmpAssetDir = "${target.rootDir}${pathSeparator}tmpasset${pathSeparator}PreloadPlugin${pathSeparator}assets"
val assetDir = File(tmpAssetDir)
println(tmpAssetDir)
// 執(zhí)行網(wǎng)絡(luò)請(qǐng)求,獲取預(yù)加載信息
if (!assetDir.exists()) {
assetDir.mkdirs()
}
// 緩存文件
val cacheFile = File(tmpAssetDir, "app_service_api.json")
// 執(zhí)行網(wǎng)絡(luò)請(qǐng)求
val okHttpClient = OkHttpClient()
val request = Request.Builder().url("https://api.uomg.com/api/rand.qinghua?format=json")
.get().build()
val response = okHttpClient.newCall(request).execute().body?.string()
// 寫入緩存文件
FileUtils.writeStringToFile(cacheFile, response, "utf-8")
target.afterEvaluate { project ->
val android = project.extensions.getByName("android") as AppExtension
val mainSourceSet = android.sourceSets.getByName("main")
// 動(dòng)態(tài)添加asset目錄
mainSourceSet.assets.srcDirs(tmpAssetDir)
println("source assets = ${mainSourceSet.assets.srcDirs}")
}
} else {
throw IllegalStateException("只能在主工程模塊中使用資源預(yù)加載插件!")
}
}
}
使用
應(yīng)用了該插件build之后阿逃,會(huì)在項(xiàng)目跟目錄生成我們指定的assets目錄以及文件
最終也會(huì)打包到app里
最后
上面的demo只是一個(gè)思路,最終形態(tài)還有需要完善的地方:
- 臨時(shí)目錄需要配置ignore赃蛛,避免污染項(xiàng)目代碼
- 文件緩存的策略恃锉?每次都需要下載?