解决AndroidStudio打包apk时,不使用cocoscreator最新构建文件的问题

905 阅读2分钟

由于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中的资源就是最新的。