改造CocosCreator3.x的安卓工程

CocosCreator3.x与AndroidStudio工程对比

熟悉安卓的小伙伴可能会注意到,CocosCreator3.x(下面简称C3D)打出来的安卓工程与AndroidStudio(下面简称AS)的标准工程有些出入,对照如下

AndroidStudio工程目录:
image.png

CocosCreator3.x安卓工程目录
image.png
可以明显看出,C3D这边src是直接做为java代码的根目录的,而AS工程的src下面还有一个main目录,main下面才是资源。

但是我们发现,虽然C3D与AS标准工程不一致,但是依然能够运行,是什么原因呢?稍加探索,不难发现,C3D是在gradle里单独指定了目录

1
2
3
4
5
6
7
8
9
10
11
sourceSets.main {
java.srcDirs "../src", "src"
res.srcDirs "../res", 'res', "${RES_PATH}/proj/res"
jniLibs.srcDirs "../libs", 'libs'
manifest.srcFile "AndroidManifest.xml"
assets.srcDir "${RES_PATH}/data"
jniLibs {
// Vulkan validation layer
// srcDir "${android.ndkDirectory}/sources/third_party/vulkan/src/build-android/jniLibs"
}
}

这里,我们就初步知道了C3D和AS之间的差异。话又说回来,既然C3D的功能也能运行,那我们为什么要进行改造呢?下面来介绍两种场景,可能更依赖AS标准工程来实现(毕竟是在AS中开发的,很合理)

开发场景模拟

接入一些特定SDK

比如我们要接入信通院的oaid sdk,这个sdk就需要将supplierconfig.json这个文件拷贝到assets目录下,但C3D工程没有这个目录。
我们稍加查看路径设置,发现被指定到了${RES_PATH}/data目录,那么我们可以想到的最简单办法是将文件放到该目录下。
然而这里存在一个弊端就是每次构建data文件会被清空,需要手动重新操作,当然我们也可以写个构建插件,在钩子这里有命令移进去,但是始终不方便。
这里,我们就可以添加gradle的搜索路径来达到目的,如下

1
2
3
4
5
6
7
8
9
10
11
sourceSets.main {
java.srcDirs "../src", "src"
res.srcDirs "../res", 'res', "${RES_PATH}/proj/res"
jniLibs.srcDirs "../libs", 'libs'
manifest.srcFile "AndroidManifest.xml"
assets.srcDirs "${RES_PATH}/data", '自定义目录'
jniLibs {
// Vulkan validation layer
// srcDir "${android.ndkDirectory}/sources/third_party/vulkan/src/build-android/jniLibs"
}
}

这里,我们需要稍微注意下,因为原来只有一个目录,所以是assets.srcDir,现在是多个目录,需要改成assets.srcDirs
这里介绍了assets文件夹的使用,当然如果有java、res等可以依此类推,这样就方便类似SDK接入了。

多渠道打包

针对单个目录修改,我们已经了解了,但如果我们的应用,需要上架多个渠道,我们通常不会建立多个项目,而是一个项目借助多渠道打包,比如上线各种硬核渠道,我们可以这样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
productFlavors {
huawei {
// ...
}
xiaomi {
// ...
}
oppo {
// ...
}
vivo {
// ...
}
}

这里,我们就可以通过多渠道设置不同的参数,但有时候,我们在不同的渠道有不同的文件处理,比如icon不同等,按照上面介绍的思路,我们也可以通过修改目录的方式来设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
productFlavors {
huawei {
// ...
sourcesets {
// ...
}
}
xiaomi {
// ...
}
oppo {
// ...
}
vivo {
// ...
}
}

但是,我们如果渠道过多,则每个渠道单独设置,将会极其麻烦。与此同时,我们发现,AS似乎就不需要单独配置的。对比发现其实默认AS是支持直接读取对应渠道文件的,但是因为我们(C3D)有自定义路径,造成了该功能失效了,那么我们是否可以改回as默认结构呢?

工程改造

下面,我们对C3D的安卓工程进行一定的改造,以便与AS工程尽量对齐。

适当破坏兼容性

第一种方法是,尽量与AS几乎一样,但是会破坏与C3D原有结构的一致性,当然破坏有限。具体方法可以参考以下方式:因为src文件被占用,所以我们要把src下面的java代码移到src/main/java下,然后将对应的文件路径设置好,如下

1
2
3
4
5
java.srcDirs "../src", "src/main/java"
res.srcDirs "../res", 'res', "${RES_PATH}/proj/res", "src/main/res"
jniLibs.srcDirs "../libs", 'libs'
manifest.srcFiles "AndroidManifest.xml"
assets.srcDirs "${RES_PATH}/data", src/min/assets

这里,我们其实也只破坏了java代码位置的兼容性,如果项目没有对此进行额外处理,那其实也不受影响。另外,我们还可以对AndroidManifest.xml也对齐,即删除该处配置,将AndroidManifest.xml移到src/main目录下。

不破坏原有结构

当然,如果你想完全不破坏原有结构,也可以自己定义main的根目录,比如newsrc,则改后的配置为

1
2
3
4
5
6
7
8
9
10
11
sourceSets.main {
java.srcDirs "../src", "src", "newsrc/main/java"
res.srcDirs "../res", 'res', "${RES_PATH}/proj/res", "newsrc/main/res"
jniLibs.srcDirs "../libs", 'libs'
manifest.srcFiles "AndroidManifest.xml"
assets.srcDirs "${RES_PATH}/data", "newsrc/main/assets"
jniLibs {
// Vulkan validation layer
// srcDir "${android.ndkDirectory}/sources/third_party/vulkan/src/build-android/jniLibs"
}
}

这样,多渠道打包,就可以单独设置文件夹,而不需要进行配置

1
2
3
4
5
6
7
8
app
/src
/main
/java、res、assets ....
/channel1
/java、res、assets


至此工程改造结束。考虑到第一种破坏性并不大,而且可以减少目录分散程度以及与AS工程更接近,所以我这边更推荐第一种方式,同时我也将方式1给提交了pr Android模板工程对齐官方默认模板