原理介绍
对于移动平台游戏开发,应用层与原生层的通信处理是十分必要的。
最常见的应用就是接入第三方SDK,比如QuickSDK,以Android为例,QuickSDK是Java代码实现的,如果想要在应用层主动调用登录,注销,上传数据这些操作,就必须用到这种反射机制了,IOS也是类似的逻辑。
Creator 为此提供了专门的接口,就是 JsbBridgeWrapper
, 具体的介绍上官方文档
JsbBridgeWrapper 基于原生反射机制的事件处理
简单来说就是JS/TS与原生端相互收发消息的机制
基本使用示范
既然是相互直接收发消息,那么注册和发送消息的接口就是少不了的。
应用端TS代码:
import { native } from 'cc'
// 接受来自原生平台的事件 “A”
// 当事件 “A” 触发时, ‘this.A’ 方法会被调用
native.jsbBridgeWrapper.addNativeEventListener("A", (usr: string) => {
this.A(usr);
});
// 发送事件“B”到原生层,传输的参数是arg,目前支持的只有string类型
native.jsbBridgeWrapper.dispatchEventToNative("B", arg);
Android端Java代码:
JsbBridgeWrapper jbw = JsbBridgeWrapper.getInstance();
// 注册监听
jbw.addScriptEventListener("requestLabelContent", arg ->{
System.out.print("@JAVA: here is the argument transport in" + arg);
// 消息派发
jbw.dispatchEventToScript("changeLabelContent","Charlotte");
});
IOS端Objective-C代码:
JsbBridgeWrapper* m = [JsbBridgeWrapper sharedInstance];
OnScriptEventListener requestLabelContent = ^void(NSString* arg){
JsbBridgeWrapper* m = [JsbBridgeWrapper sharedInstance];
// 消息派发
[m dispatchEventToScript:@"changeLabelContent" arg:@"Charlotte"];
};
// 注册监听
[m addScriptEventListener:@"requestLabelContent" listener:requestLabelContent];
进一步封装
基本的实现步骤已经有了,后续就是在项目中实现NativeHelper机制了。
NativeHelper机制是为了让项目在今后的开发中使用更灵活,更容易拓展,也就是以后有需要过来的时候少些代码。
在应用层,封装一个单例的NativeHelper,可以全局调用
import { native, sys } from 'cc';
// 应用端接受的消息
export enum NReceiveEventID {
RTest,
RTest2,
}
let NReceiveEventCon: { [key: number]: string } = {
// 测试
[NReceiveEventID.RTest]: "RTest",
// 测试2
[NReceiveEventID.RTest2]: "RTest2",
}
export class NativeHelper {
// 单例的实现
private static _instance:NativeHelper = null;
public static getInstance():NativeHelper {
if (this._instance == null){
this._instance = new NativeHelper();
this._instance.init();
}
return this._instance;
}
private init(){
this.registerAllScriptEvent();
}
public registerAllScriptEvent() {
if (sys.platform == sys.Platform.ANDROID
|| sys.platform == sys.Platform.IOS){
Object.keys(NReceiveEventCon).forEach(key=>{
let event = NReceiveEventCon[key];
native.jsbBridgeWrapper.addNativeEventListener(event, (usr?: string) => {
console.log("receive from java event=" + event);
console.log("receive from java usr=" + usr || "null");
//TODO
});
})
}else{
// TODO
}
}
public dispatchEventToNative(event: string, arg?: string) {
if (sys.platform == sys.Platform.ANDROID
|| sys.platform == sys.Platform.IOS){
native.jsbBridgeWrapper.dispatchEventToNative(event, arg);
}else{
// TODO
}
}
}
// 单例的对象
export let NativeMgr = NativeHelper.getInstance();
在原生层以Android端为例,封装一个NativeManager类来实现
package com.cocos.game;
import android.app.Activity;
import android.util.Log;
import com.cocos.lib.JsbBridgeWrapper;
public class NativeManager {
public static String TAG = "NativeManager";
public static JsbBridgeWrapper jbw ;
public static void start(Activity main){
jbw = JsbBridgeWrapper.getInstance();
//Original method
jbw.addScriptEventListener("sendMsg1", arg ->{
Log.i(TAG, "JAVA: event=nativeShowAd, arg=" + arg);
NativeManager.dispatchEventToScript("RTest", "data3");
// TODO
});
}
public static void dispatchEventToScript(String eventName, String arg){
//Original method
jbw.dispatchEventToScript(eventName,arg);
}
public static void dispatchEventToScript(String eventName){
//Original method
jbw.dispatchEventToScript(eventName);
}
}
应用层例子如下:
NativeMgr.dispatchEventToNative("sendMsg1", "data");
调试中遇到的问题
首先要发布选择android平台,具体可参照官方文档-构建发布面板详解
成功后用android studio 打开项目,项目目录为
./GameFrame\build\android\proj
新建的java源码目录为
./GameFrame\native\engine\android\app\src\com\cocos\game
在真机或是模拟器上调试运行后就能看到结果。
后续如果加进来应用层的消息派发机制,这块的逻辑就完整了。敬请期待吧。
今天的分享就到这里,祝大家早日实现自己的财务自由,可以想吃什么吃什么,想买什么买什么,下次再会。