赞
踩
语言环境
Cocos2dx 3.6
lua 5.1
java 1.8.0_144
本节问题:
lua 通过 luaj与java交互,在java中,如何回调lua?若要处理的事件代码必须在多线程中执行,又该如何保证数据的连贯统一?
本节发送的问题以及解决思路为本人实测,真实有效。
由lua 调用java 实现‘复制粘贴’说起:
复制不多说,网上成功的例子一大把,说说粘贴,
先上一段 lua 中调用java函数的代码
- --调用java 取剪贴板数据
- --回调函数
- function AndroidFunc:getClipboard(callback)
- --*注意:此为java回调luaj用例*
- --*/回调函数作为参数以int【I】型传参
- local resTab = {-1,'权限不足'}
- --resTab =
- local function clipboardCallbackFromJava(params)
- -- print("ClipboardCallbackFromJava datas->"..params)
- -- dump(params)
- params = tostring(params)
- if params == '@-1#' then --权限不足
- resTab = {-1,'权限不足'}
- elseif params == '@0#' then --内容为空
- resTab = {0,''}
- else
- resTab = {0,params}
- end
- if type(callback) == 'function' then
- callback(resTab)
- end
- end
-
- local className = "org/cocos2dx/lua/AppActivity"
- local funcName = "getPasteToClipboard"
- local args = {clipboardCallbackFromJava}
- local sigs = "(I)V"
- local ok, ret = luaj.callStaticMethod(className, funcName , args ,sigs)
- --多线程先执行
- if not ok then
- print("取剪贴板数据调用失败 失败代码:", ret)
- resTab = {-1,'权限不足'}
- if type(callback) == 'function' then
- callback(resTab)
- end
- else
- resTab = {}
- print("取剪贴板数据调用成功 返回结果:", ret)
- end
- end
这是我改完后的版本,要注意的点:
1.如何将一个函数以参数的形式传进java,这一点在 luaj 中有介绍,我不多说,这里提供下地址,自己去看,
JIN中java类型的定义:https://www.cnblogs.com/tianshuai11/archive/2012/03/26/2477175.html
luaj的概念用法:https://blog.csdn.net/MartinLutherSu/article/details/50470259?locationNum=1&fps=1
2.接下来是java层面
从以上代码能看出我的功能函数写在了‘org.cocos2dx.lua.AppActivity’这个类中,写的比较杂,直接写在AppActivity这种用法不推荐,我是懒得改了,java粘贴功能的实现请参照:
cocos-lua实现复制粘贴 https://www.cnblogs.com/U-tansuo/p/clip.html
- // 粘贴(取剪贴板数据)
- public static void getPasteToClipboard(int callbackFuncID) {
- final Context context = instance; // 参数要加final关键字,否则内部类不能访问
- clipboardCallbackFunc = callbackFuncID //回调主线程的关键
- if (clipboardCallbackFunc != -1){
- try {
- Runnable runnable = new Runnable() {
- public void run() {
- android.content.ClipboardManager clipboard = (android.content.ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
- android.content.ClipData clip = clipboard.getPrimaryClip();
-
- String resText = "@-1#"; //使用特殊字符串标识
- if (clip != null){ //权限不足,获取失败
- android.content.ClipData.Item textItem = clip.getItemAt(0);
- if (textItem != null){ //权限不足,获取失败
- if (textItem.getText() != null){ //判断文本内容
- resText = textItem.getText().toString();
- }else{
- resText = "@0#";
- };
- };
- };
- final String aa = resText;
- instance.runOnGLThread(new Runnable() {
- @Override
- public void run() {
- Cocos2dxLuaJavaBridge.callLuaFunctionWithString(clipboardCallbackFunc, aa);
- }
- });
- //PasteToClipboard = textItem.getText().toString();
- }
- };
- // getSystemService运行所在线程必须执行过Looper.prepare()
- // 否则会出现Can't create handler inside thread that has not called
- // Looper.prepare()
- instance.runOnUiThread(runnable);
- } catch (Exception e) {
- Log.d("cocos2dx", "getPasteToClipboard error");
- e.printStackTrace();
- }
- }
- }
看过我上面的代码就应该明白,在执行 'getSystemService'时不能在主线程 即 handler 中运行,否则会出错,代码不要照搬啊,android.content.ClipboardManager 是我已经引入的包,若没有引入,可以通过上下文对象来获取,看到这个函数的参数 就知道 luaj 中的 callJavaStaticMethod 若传递的参数是函数 则以‘ int’来标识函数地址,这里我是这么理解的 ,lua向java 传递了一个函数,java实际拿到的是其钩子,‘clipboardCallbackFunc’这个变量是我在函数外部定义的,具体定义为:
public static int clipboardCallbackFunc = -1; //获取剪贴板粘贴的lua回调函数
回调的关键:
Cocos2dxLuaJavaBridge.callLuaFunctionWithString(clipboardCallbackFunc, resText);
完成以上步骤,就已经完成了一大半了,接下来就是实测,我这边测是没问题的
总结:
lua在调用java代码时尽量不要在主线程中进行操作,否则一旦阻塞进程就很严重了
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。