由于gradle的版本更新后,导致AndroidStudio打包apk的时候,没有使用cocoscreator最新构建的文件。要解决这个问题,需要了解下AndroidStudio的构建流程。
Android构建
android apk的构建是由Gradle插件完成的,每次构建都会执行很多构建任务,比如编译java,C++等。各个任务之间存在依赖关系,插件根据依赖关系执行对应任务,最终生成Apk.
mergeAssets就是其中的一个构建任务,它的作用就是将Android 项目及各个依赖 Library 的 Assets 资源文件合并到构建暂存目录,方便最后打包。
Cocoscreator就是在这个任务最后(variant.mergeAssets.doLast),添加了一些复制任务,将脚本资源等等内容复制到 Android Apk 的 Assets 资源目录中。
在gradle中的代码如下:
android.applicationVariants.all { variant ->
// delete previous files first
delete "${buildDir}/intermediates/merged_assets/${variant.dirName}"
// 复制Cocoscreator资源到Android的Assets目录下
variant.mergeAssetsProvider.get().doLast {
def sourceDir = "${buildDir}/../../../../.."
copy {
from "${sourceDir}/assets"
into "${outputDir}/assets"
into outputDir.dir("assets")
}
copy {
from "${sourceDir}/src"
into "${outputDir}/src"
into outputDir.dir("src")
}
copy {
from "${sourceDir}/jsb-adapter"
into "${outputDir}/jsb-adapter"
into outputDir.dir("jsb-adapter")
}
copy {
from "${sourceDir}/main.js"
from "${sourceDir}/project.json"
into outputDir
}
}
}
原因
问题就出在上面的代码中:
delete "${buildDir}/intermediates/merged_assets/${variant.dirName}"
由于不同的gradle版本,gradle构建的暂存目录不一样,而上面的代码是删除的是一个固定的目录,代表不了不同版本gradle的暂存目录。因此会出现AndroidStudio构建apk时,有时可以使用到最新的资源文件,有时用到的还是老的资源文件。
解决方案
不同gradle版本对应的目录又不一样
- grade4.0及以下需要用
variant.mergeAssets.outputDir - gradle5.0及以上的需要使用
variant.mergeAssetsProvider.get().outputDir。
具体修改如下:
// gradle 4.0以下版本
delete variant.mergeAssets.outputDir
// gradle 5.0以上笨笨
delete variant.mergeAssetsProvider.get().outputDir
不过这里有人会问,为何每次构建都要删除这个暂存目录?
那是因为Groovy 的 Copy 任务会自动识别本次是否应该执行复制。比如:复制文件A到一个目录两次,在第二次执行的时候,同名文件则不会复制,而是会 UP-TO-DATE 不会再执行。
因此为了让Cocoscreator每次构建后,AndroidStudio都能用到所有最新的文件,必须先删除暂存目录中的所有文件,重新复制一遍Cocoscreator的资源到安卓的缓存目录中。这样Apk中的资源就是最新的。