引言:本文作者「羽毛先生」,他将基于 v3.4.2,介绍 Cocos 的 原生二次开发流程以及 JSB 进行 层与引擎 TS/JS 层进行相互调用的过程。Demo 源码见文末。
最近在开发的一个游戏进入到了安卓 SDK 接入的相关工作,但是构建安卓工程后,发现结构跟以往的 jsb-link 差别比较大,项目目录结构和以前也有所不同。本次就聊一聊 Cocos 的安卓原生二次开发,为开发的小伙伴提供一些参考。
分析过程
首先查阅一下官方文档中对构建目录[1]、二次开发[2]的说明。
构建目录
二次开发
注意事项
接着查看本地文件。
/build//proj目录:
目录:
跟随文档,使用 打开 build//proj,发现找不到上述的 .xml,build.,以及 ////app/com/cocos/game/,这时候只要切换一下显示模式为 即可。
切换后即可看到相关的原生文件。
通过 中使用 资源管理器打开 .java 可以发现 .java位于 ///app/src/com/cocos/game 目录中。
总结:在 build//proj 使用 进行开发,生效文件位于 // 中,对 目录做版本管理,同时需去除 下的 build 目录(编译过程临时生成内容)。
build/ 目录中为 Cocos 配置的 内容,随工程改变,不需要做单独的版本管理。
接入流程示例
接下来以 SDK 为例,介绍一下完整的安卓原生工程二次开发流程。下载好 SDK 后打开 SDK 文档,参照文档指引进行接入。
SDK 接入文档
首先在编辑器中进行安卓原生构建。构建的相关选项请参考官方文档[3],文档有很详细的说明。
构建完成后,可在工程目录下看到 、build/ 两个目录。
接着使用 打开 build//proj 并且切换到 显示模式。
然后我们来根据 SDK 接入文档进行接入。
▶1、导入 SDK。
在 ///app/ 目录下新建 libs 目录(可在 中通过 show in 使用 资源管理器打开,自动跳转到该目录)。
在 \\app 下创建 libs 目录,复制 SDK 中的 aar 等文件到 libs 下,并在 app 所属的 build. 中添加依赖。
此处需要注意 libs 目录的中的 aar/jar 文件并非 接入文档中的 .jar,而是 .0.3.jar(下载 SDK 时提供的文件名),在接入其他的 SDK 中也常常会有这样的细节问题,需要注意以免被坑。
▶2、配置混淆规则。
打开 app 所属 -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");
}
});
}
}
.java,建议可以简单了解下 各个生命周期函数执行时机以及机制:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// DO OTHER INITIALIZATION BELOW
SDKWrapper.shared().init(this);
TDSDK.getInstance().init();
}
▶5、接入完成后可以直接在 中进行打包。apk 生成路径:-001projbuild\apk
-001 为在 构建界面的构架任务名。
也可以在 Cocos 构建工具中点击生成进行打包。apk 生成路径:build-001 -001 为在 构建界面的构架任务名。
如果进行了 JS 层代码修改安卓sdk下载,则还需要通过编辑器的构建流程进行工程构建,然后再进行生成,使代码生效。
按照引擎设计, 目录生成后,再次构建将跳过这部分的生成,避免影响已经开发的 SDK、 C++ 等原生定制的内容,在此也建议将 目录加入 git/svn 版本控制。
▶6、打包测试,运行成功,后台可收到激活设备,大功告成!!!
JS/TS与方法互调
层接入完毕后,则需要实现 Java 与 TS 的互调。查阅官方文档[4]可知:
示例:
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 挂在 上,并且在 Cocos 根目录创建 .d.ts 文件对 tdsdk 进行全局声明(文件名随意,不跟已有的冲突即可),方便别处调用时可以进行代码提示。
.d.ts:
import { tdsdk } from "./assets/script/tdsdk";
declare global {
interface Window {
tdsdk: tdsdk
}
}
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,请在规定线程中调用(),避免崩溃,这里建立规范统一在规定线程中调用。
运行结果:
更高级的互调方式,请参考「腾讯在线教育部技术博客」中的 JSB 自动绑定方案安卓sdk下载,主要介绍了 C++ 与 JS 的互调:
资源下载