creator-Android交互与构建
title: creator-Android交互与构建
categories: Cocos2dx
tags: [creator, Android, native]
date: 2023-04-04 16:20:39
comments: false
mathjax: true
toc: true
creator-Android交互与构建
前篇
- 跨平台发布游戏 - https://docs.cocos.com/creator/2.2/manual/zh/publish/
使用的相关配置
- creator 版本 3.7.2
- sdk api 31
- ndk 版本: android-ndk-r25c-windows.zip, https://github.com/android/ndk/wiki
配置 sdk, ndk
-
文件 -> 偏好设置 -> 程序管理器
构建结构
-
第一次构建会在项目内生成原生的模板, 里面包含不同平台, 如: 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 中增加一个静态方法
public static void testApi(final String jsonMsg, final String funcKey) {Log.d(TAG, String.format("--- jsonMsg: %s, funcKey: %s", jsonMsg, funcKey));CocosHelper.runOnGameThread(new Runnable() {@Overridepublic 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 入口中去掉用这个方法
@ccclass() 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 报错
-
报错
Execution 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_EGLlinked by target "cocos_engine" in directory E:/workspace/cocos/TestAtlas/native/engine/android
-
原因是 ndk 版本错误, 尝试换成最新版本试试
生成时 gradle 任务报错
-
报错
Execution 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 adependency'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
android {compileSdkVersion 33defaultConfig {targetSdkVersion 33} }
-
方法二: 如果不需要的话, 去掉依赖模块中的
implementation 'androidx.appcompat:appcompat:1.6.1'
引入
-
找不到 java 的 native 方法
-
报错找不到 native 方法
-
原因有可能是配置了混淆, 把定义的 native 方法 (由于没有被引用) 都干掉了, 验证方法很简单, 用工具 jadx 打开 apk 看看就能看到 native 方法是不是没了
-
解决办法, 在混淆配置文件 proguard-rules.pro 中忽略掉 native 方法
####################### 自定义混淆规则 -keep class com.yang.androidaar.MainActivity{public static <methods>; #保持该类下所有静态方法不被混淆, 这些是 cocos 的 native 方法 }