creator-Android交互与构建
creator-Android交互与构建
前篇
使用的相关配置
- creator 版本 3.7.2
- sdk api 31
- ndk 版本: android-ndk-r25c-windows.zip, https://github.com/android/ndk/wiki
配置 jdk, sdk, ndk
下载 Java SDK(JDK), 编译 Android 工程需要本地电脑上有完整的 Java SDK 工具,请到以下地址下载:Java SE Development Kit 8 Downloads
文件 -> 偏好设置 -> 程序管理器
构建结构
第一次构建会在项目内生成原生的模板, 里面包含不同平台, 如: android
- 构建出来的 as 工程: build\android-001\proj, 用 as 打开可以看到一下结构
结构图
- 所以项目内的 app 目录就是需要我们配置的目录
js 与 Android 交互
- 如何在 Android 平台上使用 JavaScript 直接调用 Java 方法 - https://docs.cocos.com/creator/manual/zh/advanced-topics/java-reflection.html
实际操作流程
在入口 activity 类 com.cocos.game.AppActivity 中增加一个静态方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public static void testApi(final String jsonMsg, final String funcKey) {
Log.d(TAG, String.format("--- jsonMsg: %s, funcKey: %s", jsonMsg, funcKey));
CocosHelper.runOnGameThread(new Runnable() {
@Override
public void run() {
CocosJavascriptJavaBridge.evalString("console.log(\"--- call from js\")");
String msgTxt = "{aaa: \"wolegequ\"}";
String keyTxt = "world 222";
String callStr = String.format("window['gOnAndroidCall']('%s', '%s')", msgTxt, keyTxt); // gOnAndroidCall 是 js 中注册的全局方法
CocosJavascriptJavaBridge.evalString(callStr);
}
});
}在 js 入口中去掉用这个方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18()
export class GameMgr extends Component {
start() {
console.log('--- GameMgr start')
// 注册一个全局方法, 接收 jave 调用
window["gOnAndroidCall"] = this.onNativeCall.bind(this)
if (sys.platform === sys.Platform.ANDROID) {
console.log('--- call ANDROID')
native.reflection.callStaticMethod("com/cocos/game/AppActivity", "testApi", "(Ljava/lang/String;Ljava/lang/String;)V", "Tom 001", "Betty 002");
}
}
onNativeCall(jsonMsg: string, funcKey: string) {
console.log(`--- gOnAndroidCall, jsonMsg: ${jsonMsg}, funcKey: ${funcKey}, node: ${this.node.name}`)
}
}构建 (修改了 js 就需要构建) -> 生成 (修改了 java 就需要生成)
安装测试
native 开发流程
我比较喜欢将所有的 native api 都集中到一个库模块中, 然后这个库导出为一个 jar 集成到主工程中
和 unity 的 native 流程一样, 参考: unity-Android库开发工作流.md 一样
开发工程结构
- app : 就是所有 cocos 引擎里用到的 native api 的功能 库模块
- testapp : 是测试 native 库模块的 application 模块, 也就是可以打包最简单原生 apk 的模块
- libservice : 是 app 库模块 里用到了相关 cocos 的 api
- libservice : 是 app 库模块 里用到了相关 cocos 的 api
在 app 库模块开发完后, 通过 testapp 主模块 测试, 没问题后, 把 app 库模块导出为 jar, 如: classes.jar
打包工程结构
- 这个 cocos 生成的 as 工程, 把上面导出的 classes.jar 引入到 主模块 中, 就可以使用所有 库模块 里的 api
踩坑
生成时 ndk 报错
报错
1
2
3
4
5Execution failed for task ':TestAtlas:generateJsonModelRelease'.
> E:\workspace\cocos\TestAtlas\native\engine\android\CMakeLists.txt : C/C++ release|armeabi-v7a : CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
Please set them or make sure they are set and tested correctly in the CMake files:
LIB_EGL
linked by target "cocos_engine" in directory E:/workspace/cocos/TestAtlas/native/engine/android原因是 ndk 版本错误, 尝试换成最新版本试试
生成时 gradle 任务报错
报错
1
2
3
4
5
6
7Execution failed for task ':TestAtlas:checkReleaseAarMetadata'.
> Multiple task action failures occurred:
> A failure occurred while executing com.android.build.gradle.internal.tasks.CheckAarMetadataWorkAction
> The minCompileSdk (33) specified in a
dependency's AAR metadata (META-INF/com/android/build/gradle/aar-metadata.properties)
is greater than this module's compileSdkVersion (android-31).
Dependency: androidx.appcompat:appcompat-resources:1.6.1.原因是因为项目的 application 模块依赖的某个模块中, 引入了
implementation 'androidx.appcompat:appcompat:1.6.1'
这个库, 这个库的指定的最小编译的 sdk 是 33, 而项目指定编译的 sdk 为 31解决办法有两个
方法一: (推荐) 将项目 application 模块的的编译 sdk 设置为 33
1
2
3
4
5
6android {
compileSdkVersion 33
defaultConfig {
targetSdkVersion 33
}
}方法二: 如果不需要的话, 去掉依赖模块中的
implementation 'androidx.appcompat:appcompat:1.6.1'
引入
找不到 java 的 native 方法
报错找不到 native 方法
原因有可能是配置了混淆, 把定义的 native 方法 (由于没有被引用) 都干掉了, 验证方法很简单, 用工具 jadx 打开 apk 看看就能看到 native 方法是不是没了
解决办法, 在混淆配置文件 proguard-rules.pro 中忽略掉 native 方法
```json
####################### 自定义混淆规则
-keep class com.yang.androidaar.MainActivity{public static <methods>; #保持该类下所有静态方法不被混淆, 这些是 cocos 的 native 方法
}