creator-Android交互与构建

creator-Android交互与构建


前篇

使用的相关配置


配置 jdk, sdk, ndk

  • 下载 Java SDK(JDK), 编译 Android 工程需要本地电脑上有完整的 Java SDK 工具,请到以下地址下载:Java SE Development Kit 8 Downloads

  • 文件 -> 偏好设置 -> 程序管理器

    image-20230404162420360


构建结构

  • 第一次构建会在项目内生成原生的模板, 里面包含不同平台, 如: android

    image-20230404162540950

    • 构建出来的 as 工程: build\android-001\proj, 用 as 打开可以看到一下结构
  • 结构图

    image-20230404163357481

    • 所以项目内的 app 目录就是需要我们配置的目录

js 与 Android 交互

实际操作流程

  1. 在入口 activity 类 com.cocos.game.AppActivity 中增加一个静态方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    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() {
    @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);
    }
    });
    }
  2. 在 js 入口中去掉用这个方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    @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}`)
    }
    }
  3. 构建 (修改了 js 就需要构建) -> 生成 (修改了 java 就需要生成)

  4. 安装测试

    image-20230404174606949


native 开发流程

我比较喜欢将所有的 native api 都集中到一个库模块中, 然后这个库导出为一个 jar 集成到主工程中

和 unity 的 native 流程一样, 参考: unity-Android库开发工作流.md 一样

  1. 开发工程结构

    image-20230405215722665

    • app : 就是所有 cocos 引擎里用到的 native api 的功能 库模块
    • testapp : 是测试 native 库模块的 application 模块, 也就是可以打包最简单原生 apk 的模块
    • libservice : 是 app 库模块 里用到了相关 cocos 的 api
    • libservice : 是 app 库模块 里用到了相关 cocos 的 api

    在 app 库模块开发完后, 通过 testapp 主模块 测试, 没问题后, 把 app 库模块导出为 jar, 如: classes.jar

  2. 打包工程结构

    image-20230405220249975

    • 这个 cocos 生成的 as 工程, 把上面导出的 classes.jar 引入到 主模块 中, 就可以使用所有 库模块 里的 api

踩坑

生成时 ndk 报错

  • 报错

    1
    2
    3
    4
    5
    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_EGL
    linked by target "cocos_engine" in directory E:/workspace/cocos/TestAtlas/native/engine/android
  • 原因是 ndk 版本错误, 尝试换成最新版本试试


生成时 gradle 任务报错

  • 报错

    1
    2
    3
    4
    5
    6
    7
    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 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

  • 解决办法有两个

    1. 方法一: (推荐) 将项目 application 模块的的编译 sdk 设置为 33

      1
      2
      3
      4
      5
      6
      android {
      compileSdkVersion 33
      defaultConfig {
      targetSdkVersion 33
      }
      }
    2. 方法二: 如果不需要的话, 去掉依赖模块中的 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 方法
    

    }