背景
开发过程中会有这样一种需求:app需要从远程获取部分前置资源(比如接口配置信息)。通常做法是打包前手动内置到assets中,但这种方式比较低效,今天我们就来讨论一种自动化的过程
自定义Gradle插件获取远程资源并配置到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)
// 执行网络请求,获取预加载信息
if (!assetDir.exists()) {
assetDir.mkdirs()
}
// 缓存文件
val cacheFile = File(tmpAssetDir, "app_service_api.json")
// 执行网络请求
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")
// 动态添加asset目录
mainSourceSet.assets.srcDirs(tmpAssetDir)
println("source assets = ${mainSourceSet.assets.srcDirs}")
}
} else {
throw IllegalStateException("只能在主工程模块中使用资源预加载插件!")
}
}
}
使用
应用了该插件build之后,会在项目跟目录生成我们指定的assets目录以及文件
9D9EF183-29A7-4860-A7D4-8AA04EFDF775.png
最终也会打包到app里
2EF39414-FE1A-440d-888A-0B2E976CE8EC.png
最后
上面的demo只是一个思路,最终形态还有需要完善的地方:
- 临时目录需要配置ignore,避免污染项目代码
- 文件缓存的策略?每次都需要下载?
网友评论