最近在接触一个新事物,Egret引擎。话说一个用于开发Html5游戏的引擎,其使用js的超集.ts的TypeScrice来开发。
而,最近的需求是,需要把利用这个Egret引擎开发的Html5游戏与公司开发的SDK结合起来。就是说,需要把这个Html5游戏打包成为apk,并在这个apk中使用我们的SDK功能。
如果在android使用过Html5开发过页面的话,我们都知道,html5与android的交互靠的是js脚本.在android端打开这个html5页面的时候,给这个页面的window中设置一个js类。Html5在通过这个js类来调用android端本来定义好接口,来完成交互。
但Egret引擎是一个代码集,他们本来已经对这个封装好了,所以我们主要根据他们的文档来就可以了。
详细参考:Egret与Native的通讯技巧
看过上面的文章之后,其实脑海里面已经好清晰了,基本交互原理和java代码差不多,但问题是,如果我们是一个写android工程或java工程的人员,这里该如何入手呢?
第一步:首先我们要先实现上面文章的这个列子
根据网站教程:Egret小白快速上手。 我们可以现在来体验一下Egret引擎的IDE编写代码。有两个点需要知道:1.如果调用方法 ,在Egret wind的IDE中编写ts代码,其风格有点类似于js,又类似于OC。熟悉其书写方法,和类的使用,变量的声明等。2.如果使用点击事件,其实就是响应用户操作,因为这个可以建立按钮,方便我们调式的时候,通过点击按钮来调用android端接口。
第二步:在window中把Egret工程打包成apk.我把这个弱智的打包命令封装成了一个批处理文件。
只要把Egret里面的工程html5Demo的文件夹拖动到批处理文件中,就会自动生成一个对应的android工程,免去敲打命令的烦恼。
主要有两个文件:1.配置文件:properties.ini 2.批处理命令.bat
配置文件内容:
############android工程名称############ android_proj_name=Fish_Native_2 ############android工程模板############ #1 D:\Html5ToAndroid\egret-android-support-3.0.0 #2 D:\Egret\egret-android-support-2.5.6 android_model=D:\Html5ToAndroid\egret-android-support-3.0.0
批处理命令内容:
@echo off setlocal enabledelayedexpansion for /f "delims=" %%a in ('type "properties.ini"^| find /i "="') do ( set %%a ) cd /d "%~dp0" @set H5_path=%1 @set Android_path=%cd%\%android_proj_name% @echo H5工程地址 = %H5_path% @echo 生成的android工程地址 = %Android_path% @echo 用于生成android工程的模板 = %android_model% @echo ----------------生成android工程----------------------- @call egret create_app %Android_path% -f %H5_path% -t %android_model% pause
第三步:编写Egret端代码,监听Native发送来信息和向Native端发送信息。
在main.ts的createGameScene方法界面加入如下代码:
this.setNativeListener();//监听android发来的信息 this.callAndroid();//调用android
然后分别实现这两个方法:
private callAndroid():void{ egret.ExternalInterface.call("callAndroid","i am from Egret"); } private setNativeListener(): void{ egret.ExternalInterface.addCallback("sendToJS",function(message:string){ console.log("message from Native is = "+message); //注意 如果再在这里调用main.ts的其他方法的话 使用this.调用的话会报错 this.showMessage(message);//编译不报错 但运行报错 }); } private showMessage(message:string):void{ console.log("showMessage----- message= " + message); }
这里面引发了第一个坑,this.的引用。为了应对这个坑,可以使用另一种方式实现callback方法。
private setNativeListener(): void{ egret.ExternalInterface.addCallback("sendToJS",this.sendToJScallback); } private sendToJScallback(message: string){ console.log("message from Native is = " + message); this.showMessage(message);//这里可以使用this.引用 调用其他方法。 } private showMessage(message:string):void{ console.log("showMessage----- message= " + message); }
这里包含了js中this的引用机制,虽然不是很了解,也不知道这样做法是否正确,反正可以正常运行就ok了,我们只是用来测试的。
第四步:把Egret工程生成Android工程。
在Eclipse中导入工程,并且在主activity中先设置监听。并再接收到Egret端发送过来的信息后,向Egret发出信息。private void setInterfaces() { // Egret(TypeScript)-Runtime(Java)通讯 // setRuntimeInterface(String name, IRuntimeInterface interface) 用于设置一个runtime的目标接口 // callEgretInterface(String name, String message) 用于调用Egret的接口,并传递消息 gameEngine.setRuntimeInterface("sendToNative", new IRuntimeInterface() { @Override public void callback(String message) { Log.d(TAG, message); gameEngine.callEgretInterface("sendToJS", "A message from android"); } }); }
第五步:运行这个android工程,查看log.
经过以上步骤,我们已经熟悉如何在Egret端与Native端进行消息通讯了,那么如何定义他们之间的协议。由其方法我们可以知道,他们的消息只允许发送一个string的字符串。那么最好就使用json协议来定义了,方便两边进行数据解析,可是android端可以使用很多json帮助类,但Egret端呢?如何将一个实体生成Json字符串和解析一个字符串变成一个实体类呢。
其实可以在Egret的WebSocket章节看到,Egret中包含一个关键词:JSON.
这个JSON关键词中包含两个非常有用的方法:
一个是把json字符串解析成为一个 JSobject, 一个是把JSObject转换成json字符串。有了这个api之后,我们就只定义Egret端与Android端的通讯协议了。