Cocos Creator Android打包踩坑记录:Gradle配置与常见问题解决

Cocos Creator Android打包踩坑记录:Gradle配置与常见问题解决

这篇文章整理我在2021年使用Cocos Creator进行Android打包时遇到的各种坑和解决方案。当时Android Studio和Gradle版本升级频繁,很多配置都需要手动调整。

Gradle配置升级踩坑记录

修改setting.gradle配置

Android Studio升级后,setting.gradle需要修改,否则会出现模块找不到的错误。

文件路径:

1
jsb-default/frameworks/runtime-src/proj.android-studio/setting.gradle

修改前:

1
include ':libcocos2dx',':game', ':instantapp'

修改后:

1
include ':libcocos2dx'

说明:移除gameinstantapp模块,这些是给Google Instant使用的,如果不需要可以直接屏蔽对应模块。

修改CocosAndroid.mk

文件路径:

1
jsb-default/frameworks/runtime-src/proj.android-studio/jni/CocosAndroid.mk

修改前:

1
LOCAL_MODULE := cocos2djs_shared

修改后:

1
LOCAL_MODULE := cocos2djs

原因:Android Studio Build时可能报错,提示找不到target “cocos2djs”。

修改app/build.gradle

修改前:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
android.applicationVariants.all { variant ->
delete "${buildDir}/intermediates/merged_assets/${variant.dirName}"

variant.mergeAssets.doLast {
def sourceDir = "${buildDir}/../../../../.."

copy {
from "${sourceDir}/assets"
into "${outputDir}/assets"
}

copy {
from "${sourceDir}/src"
into "${outputDir}/src"
}

copy {
from "${sourceDir}/jsb-adapter"
into "${outputDir}/jsb-adapter"
}

copy {
from "${sourceDir}/main.js"
from "${sourceDir}/project.json"
into outputDir
}
}
}

修改后(Gradle 5+写法):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
android.applicationVariants.all { variant ->
delete "${buildDir}/intermediates/merged_assets/${variant.dirName}"
//修改:API 'variant.getMergeAssets()'已废弃
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
}
}
}

关键改动:

  • variant.mergeAssets.doLast 改为 variant.mergeAssetsProvider.get().doLast
  • into "${outputDir}/xxx" 改为 into outputDir.dir("xxx")

资源复制问题修复

解决Android Studio运行APK不采用最新构建内容

遇到过运行APK时未使用最新构建的Cocos内容,需要修改app/build.gradle中的删除逻辑。

原代码:

1
delete "${buildDir}/intermediates/merged_assets/${variant.dirName}"

改为:

1
delete variant.mergeAssets.outputDir

Gradle 5+写法:

1
delete variant.mergeAssetsProvider.get().outputDir

Lua脚本加密配置

cocos.bat路径配置

build.gradle中配置cocos.bat的完整路径:

1
2
3
if (OperatingSystem.current().isWindows()) {
return 'C:\\cocos2d-x-3.17.2\\tools\\cocos2d-console\\bin\\cocos.bat'
}

添加assets目录配置

1
2
3
4
5
6
7
sourceSets.main {
java.srcDir "src"
res.srcDir "res"
jniLibs.srcDir "libs"
manifest.srcFile "AndroidManifest.xml"
assets.srcDirs "assets"
}

Lua编译加密配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
android.applicationVariants.all { variant ->
def outDir = "assets"

variant.mergeAssetsProvider.get().doLast {
// 复制资源文件
copy {
from "${buildDir}/../../../../../res"
into "${outDir}/res"
}
copy {
from "${buildDir}/../../../../../src"
into "${outDir}/src"
}

// Lua脚本编译和加密配置
def compileScript = (variant.name.compareTo('release') == 0)
def encryptLua = project.hasProperty('PROP_LUA_ENCRYPT') &&
(PROP_LUA_ENCRYPT.compareTo('1') == 0)

if (compileScript || encryptLua) {
def buildType = -1
if (compileScript) {
def need64 = false
def need32 = false
def abis = PROP_APP_ABI.split(':').collect{it as String}
abis.each{ abi->
if (abi.compareTo('arm64-v8a') == 0) {
need64 = true
} else {
need32 = true
}
}

if (need64 && need32) {
buildType = 2 // 同时编译32位和64位
} else if (need64) {
buildType = 1 // 仅64位
} else {
buildType = 0 // 仅32位
}
}

// 调用cocos命令编译和加密Lua文件
switch (buildType) {
case -1:
compileLua("${outDir}/src", "${outDir}/src",
false, false, encryptLua)
break
case 0:
compileLua("${outDir}/src", "${outDir}/src",
true, false, encryptLua)
break
case 1:
compileLua("${outDir}/src", "${outDir}/src/64bit",
true, true, encryptLua)
// 删除原始lua文件
delete fileTree("${outDir}/src") {
include '**/*.lua'
}
delete "${outDir}/src/cocos"
break
case 2:
compileLua("${outDir}/src", "${outDir}/src/64bit",
true, true, encryptLua)
compileLua("${outDir}/src", "${outDir}/src",
true, false, encryptLua)
break
}
}
}
}

Gradle命令行打包

查看编译状态

1
gradlew --status

根据查询到的进程ID,判断是否需要终止进程。

打印详细日志

1
gradlew assembleDebug --stacktrace

日志文件位置

  • CocosCreator.log: C:\Users\Administrator\.CocosCreator\logs - Creator构建时的日志
  • native.log: 同上目录 - 编译时的详细日志

常见问题与解决方案

Program type already present错误

错误信息:

1
2
Program type already present: android.support.v4.os.ResultReceiver
Error: Program type already present: android.support.v4.app.INotificationSideChannel

解决方案:gradle.properties中添加:

1
2
android.useAndroidX=true
android.enableJetifier=true

android.support.v4.content.FileProvider报错

问题: 使用了androidx库时不小心间接使用了旧库

解决方案: 将AndroidManifest.xml中的引用修改为:

1
2
3
4
5
// 修改前
android.support.v4.content.FileProvider

// 修改后
androidx.core.content.FileProvider

库冲突排除

如果aar文件中包含重复引入的group,导致库冲突:

1
2
3
configurations {
all*.exclude group:'com.qq.e.union', module: 'union'
}

Text must not be null or empty

解决方案:

  1. 重启Android Studio
  2. 选择左下角Build Variants,切换Active Build Variant(如从debug切换为release)

命令行打包时遇到:

1
java.net.SocketException: Connection reset

解决方案: 打开Android Studio重新同步项目后再次尝试打包。

Could not read entry错误

问题: 缓存文件被设为只读

解决方案:

  1. 定位到.bin文件,取消只读属性
  2. 或删除项目.gradle文件夹下所有内容,然后Clean项目

Expiring Daemon JVM heap space耗尽

gradle.properties中添加:

1
org.gradle.jvmargs=-Xmx2096m -XX:MaxPermSize=1048m

Several variant outputs使用相同文件名

解决方案: 搜索xxxxx文件并删除,然后重新打包。

Disable offline mode

解决方案: 选择右侧边栏Gradle -> Toggle Offline Mode

NDK路径过长问题

错误: cocos2dx_static/scripting/js-bindings/jswrapper/v8/debugger/inspector_socket_server.o.d No such file or directory

解决方案: 将编译目录放到盘符根目录(如C盘),避免路径过长。

环境变量配置

必需的环境变量

变量名 示例值
ANDROID_SDK_ROOT E:\adt-bundle-windows-x86_64-20140702\sdk
ANDROID_NDK_HOME C:\Users\Administrator\AppData\Local\Android\Sdk\ndk\20.0.5594570
NDK_ROOT E:\android-ndk-r9d
JAVA_HOME C:\Program Files\Java\jdk1.8.0_301

设置特定NDK版本

如果遇到CMake版本相关问题,在app/build.gradle中移除android{ndkVersion}配置,改为通过环境变量指定。

这些是我踩过的坑,希望对你有帮助。如果遇到其他问题,可以在评论区留言,我会尽力解答。