安卓SDK接入so easy,一文看懂Cocos Creator原生二次开发的正确姿势!
引言:本文作者「羽毛先生」,他将基于 v3.4.2,介绍 Cocos Creator 的 Android 原生二次开发流程以及 JSB 进行 Android 层与引擎 TS/JS 层进行相互调用的过程。Demo 源码见文末。
最近在开发的一个游戏进入到了安卓 SDK 接入的相关工作,但是构建安卓工程后,发现结构跟以往的 jsb-link
差别比较大,项目目录结构和以前也有所不同。本次就聊一聊 Cocos Creator 的安卓原生二次开发,为开发的小伙伴提供一些参考。
分析过程
首先查阅一下官方文档中对构建目录[1]、二次开发[2]的说明。
构建目录
二次开发
注意事项
接着查看本地文件。
/build/android/proj
目录:
查看
/build/android/proj
未发现AppActitivy.java
等文件,但是存在build.gradle
等安卓相关文件。使用Android Studio 打开目录,可以成功打开并编译。
native
目录:
查看
/native/engine/android/app
目录,存在AndroidMainfest.xml,build.gradle
等文件。
查看
/native/engine/android/app/com/cocos/game
,可以看到有AppActitivy.java
发现以上是熟悉的安卓工程目录结构。使用 Android Studio 打开目录,报错。
跟随文档,使用 Android Studio 打开 build/android/proj
,发现找不到上述的 AndroidMainfest.xml,build.gradle
,以及 /native/engine/android/app/com/cocos/game/Appactivity
,这时候只要切换一下显示模式为 Android 即可。
切换后即可看到相关的原生文件。
通过 Android Studio 中使用 Windows 资源管理器打开 AppActivty.java
可以发现 AppActivity.java
位于 native/engine/android/app/src/com/cocos/game
目录中。
总结:在 build/android/proj
使用 Android Studio 进行开发,生效文件位于 native/engine/android
中,对 native
目录做版本管理,同时需去除 native
下的 build
目录(编译过程临时生成内容)。
build/android
目录中为 Cocos Creator 配置的 service 内容,随工程改变,不需要做单独的版本管理。
接入流程示例
接下来以 TalkingData SDK 为例,介绍一下完整的安卓原生工程二次开发流程。下载好 SDK 后打开 SDK 文档,参照文档指引进行接入。
TalkingData SDK 接入文档
https://doc.talkingdata.com/posts/1025
首先在编辑器中进行安卓原生构建。构建的相关选项请参考官方文档[3],文档有很详细的说明。
构建完成后,可在工程目录下看到 native
、build/android
两个目录。
接着使用 Android Studio 打开 build/android/proj
并且切换到 Android 显示模式。
然后我们来根据 SDK 接入文档进行接入。
▶ 1、导入 SDK。
在 native/engine/android/app/
目录下新建 libs
目录(可在 Android Studio 中通过 show in explore 使用 Windows 资源管理器打开,自动跳转到该目录)。
在 \native\engine\android\app
下创建 libs
目录,复制 SDK 中的 aar
等文件到 libs
下,并在 app module
所属的 build.gradle
中添加依赖。
此处需要注意 libs
目录的中的 aar/jar
文件并非 talkingdata 接入文档中的 TalkingdataSDK.jar
,而是 SaaS_TalkingDataSDK_Android_V5.0.3.jar
(下载 SDK 时提供的文件名),在接入其他的 SDK 中也常常会有这样的细节问题,需要注意以免被坑。
▶ 2、配置混淆规则。
打开 app module
所属 proguard-rules.pro
添加混淆规则。
▶ 3、如上同理按照文档要求进行权限配置。
▶ 4、SDK 初始化、接口实现等,内容相似,则不赘述了。这里展示关键性的代码,详细内容见 Demo 源码。
TDSDK.java
:
package com.cocos.sdk;
import android.util.Log;
import com.cocos.game.AppActivity;
import com.cocos.lib.CocosHelper;
import com.cocos.lib.CocosJavascriptJavaBridge;
import com.tendcloud.tenddata.TalkingDataProfile;
import com.tendcloud.tenddata.TalkingDataProfileType;
import com.tendcloud.tenddata.TalkingDataSDK;
public class TDSDK {
static String AppID = "xxxxxxxxx";
static String Chanel = "test_channel";
static TDSDK s_self = null;
public static TDSDK getInstance(){
if (s_self == null){
s_self = new TDSDK();
}
return s_self;
}
public void init(){
TalkingDataSDK.init(AppActivity.getContext(),AppID,Chanel, "");
}
public static void onResgister(String accountId){
if (accountId==""){
accountId = TalkingDataSDK.getDeviceId(AppActivity.getContext());
}
TalkingDataProfile profile = TalkingDataProfile.createProfile();
profile.setName("");
profile.setType(TalkingDataProfileType.ANONYMOUS);
TalkingDataSDK.onRegister(accountId, profile,"");
}
public static String js2JavaTest(String str1, String str2){
Log.d("TDSDK", String.format( "js2JavaTest Success param1:%s param2: %s",str1, str2));
if (s_self!= null) s_self.java2js();
return "Java Test Success";
}
public void java2js(){
CocosHelper.runOnGameThread (new Runnable() {
@Override
public void run() {
String str1 = "param3";
String str2 = "param4";
String funcStr = String.format("window.tdsdk.java2js('%s','%s')",str1,str2);
Log.d("-----------------------", "Start Java2Js");
CocosJavascriptJavaBridge.evalString(funcStr);
Log.d("----------------------", "End Java2Js");
}
});
}
}
Appactivity.java
,建议可以简单了解下 Android 各个生命周期函数执行时机以及机制:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// DO OTHER INITIALIZATION BELOW
SDKWrapper.shared().init(this);
TDSDK.getInstance().init();
}
▶ 5、接入完成后可以直接在 Android Studio 中进行打包。apk 生成路径:android-001\proj\build\sdkDemo\outputs\apk
android-001
为在 Creator 构建界面的构架任务名。
也可以在 Cocos Creator 构建工具中点击生成进行打包。apk 生成路径:\build\android-001\publish android-001
为在 Creator 构建界面的构架任务名。
如果进行了 JS 层代码修改,则还需要通过编辑器的构建流程进行工程构建,然后再进行生成,使代码生效。
按照引擎设计,native
目录生成后,再次构建将跳过这部分的生成,避免影响已经开发的 Android SDK、native C++ 等原生定制的内容,在此也建议将 native
目录加入 git/svn
版本控制。
▶ 6、打包测试,运行成功,后台可收到激活设备,大功告成!!!
JS/TS与Android方法互调
Android 层接入完毕后,则需要实现 Java 与 TS 的互调。查阅官方文档[4]可知:
TS 调用 Java:
jsb.reflection.callStaticMethod
Java 调用 TS,使用
evalString
,请注意观察示例代码中的 evalString 函数中参数的单引号双引号使用,避免出错。
示例:
Cocos Creator TS 代码:
const classPath = "com/cocos/sdk/TDSDK";
@ccclass('tdsdk')
export class tdsdk {
private static _instance = null;
static getInstance(): tdsdk {
if (tdsdk._instance == null) {
tdsdk._instance = new tdsdk();
}
return tdsdk._instance;
}
//js调用Java
js2Java() {
if (JSB) {
log("********************start js2Java param1: title param2: content********************");
let res = jsb.reflection.callStaticMethod(classPath, "js2JavaTest", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", "title", "content");
log("返回值", res);
log("********************end js2Java param1: title param2: content********************");
}
}
//java调用js
java2js(param1: string, param2: string) {
if (!JSB) {
}
log("java2js success param3: %s param4:%s ", param1, param2);
}
}
window.tdsdk = tdsdk.getInstance();
请注意代码末尾将 tdsdk 挂在 Window 上,并且在 Cocos Creator 根目录创建 .d.ts
文件对 tdsdk 进行全局声明(文件名随意,不跟已有的冲突即可),方便别处调用时可以进行代码提示。
global.d.ts
:
import { tdsdk } from "./assets/script/tdsdk";
declare global {
interface Window {
tdsdk: tdsdk
}
}
Java 代码:
public static String js2JavaTest(String str1, String str2){
Log.d("TDSDK", String.format( "js2JavaTest Success param1:%s param2: %s",str1, str2));
if (s_self!= null) s_self.java2js();
return "Java Test Success";
}
public void java2js(){
CocosHelper.runOnGameThread (new Runnable() {
@Override
public void run() {
String str1 = "param3";
String str2 = "param4";
String funcStr = String.format("window.tdsdk.java2js('%s','%s')",str1,str2);
Log.d("-----------------------", "Start Java2Js");
CocosJavascriptJavaBridge.evalString(funcStr);
Log.d("----------------------", "End Java2Js");
}
});
}
注意在 Java 调用 JS 代码时,如果需要操作 UI,请在规定线程中调用(runOnGameThread
),避免崩溃,这里建立规范统一在规定线程中调用。
运行结果:
更高级的互调方式,请参考「腾讯在线教育部技术博客」中的 JSB 自动绑定方案,主要介绍了 C++ 与 JS 的互调:
http://docs.cocos.com/creator/manual/zh/advanced-topics/jsb-auto-binding.html?h=jsb
资源下载
点击文末【阅读原文】下载 Demo 源码
https://gitee.com/zenskcode/creatorDemo/tree/master/demos/AndroidSdkDemo-3.4.2
以上介绍完成了 SDK 接入以及 Java、TS 互调的相关用法,掌握后应该可以完成大部分安卓 SDK 的接入工作了,也可进行一些原生系统的调用。
参考链接
[1] 构建目录-官方文档
https://docs.cocos.com/creator/manual/zh/editor/publish/native-options.html?q=#%E6%9E%84%E5%BB%BA%E7%9B%AE%E5%BD%95
[2] 二次开发-官方文档
https://docs.cocos.com/creator/manual/zh/editor/publish/native-options.html?q=#%E4%BA%8C%E6%AC%A1%E5%BC%80%E5%8F%91
[3] 打包发布到原生平台-官方文档
http://docs.cocos.com/creator/manual/zh/editor/publish/native-options.html
[4] Java 反射-官方文档
http://docs.cocos.com/creator/manual/zh/advanced-topics/java-reflection.html
本文转载自公众号「羽毛不会飞」,
欢迎关注作者!
往期精彩