android中java与lua的相互调用
16lz
2021-01-25
Android Studio Lua环境配置
开发环境
1. Android Studio 3.52. java sdk: 1.8.03.android sdk:28
配置环境
添加lua支持语法支持插件,打开android studio -> File -> Settings
三方库选择
参考文章:https://gameinstitute.qq.com/community/detail/117865
Luaj 纯Java实现的Lua解析器,无需使用native
首先切换到Project目录,在gradle构建工具中添加依赖Luaj,然后同步
- Java调用Lua函数
-
在main目录下新建assets资源目录文件夹,在其下存放lua文件
-
test.lua
luaV1 = "lua String"function luaFun1() print("Lua 无参无返回值方法");endfunction luaFun2(str) return "来自Java的参数:"..str;end
- JavaTest.java
@Test public void test1( ) { Globals globals = JsePlatform.standardGlobals(); //加载Java脚本文件并编译Lua脚本 globals.loadfile("src/main/assets/test.lua").call(); //加载Lua常量 LuaValue luaStr = globals.get(LuaValue.valueOf("luaV1")); System.out.println("来自Lua的字符串" + luaStr.toString()); //加载无参无返回值函数 LuaValue lua1 = globals.get(LuaValue.valueOf("luaFun1")); lua1.call(); //加载有参有返回值函数 LuaValue lua2 = globals.get(LuaValue.valueOf("luaFun2")); //传入参数 LuaValue str = lua2.call(LuaValue.valueOf("Java~")); System.out.println(str.tostring()); }
- 运行测试方法test1输出
来自Lua的字符串lua StringLua 无参无返回值方法来自Java的参数:Java~
- Lua调用Java
- Utils.java
public void javaFun1(String str){ System.out.println("Java + " + str); } public static void javaStaticFun1(String str){ System.out.println("Static Java +" + str); }
- test.lua
function luaFun3() --创建java对象 fun1 = luajava.newInstance("com.example.luaandroid.Utils"); fun1:javaFun1("Lua");endfunction luaFun4() --绑定Java类 fun1 = luajava.bindClass("com.example.luaandroid.Utils"); fun1:javaStaticFun1("Lua");end
- JavaTest.java
@Test public void test2(){ Globals globals = JsePlatform.standardGlobals(); //加载Java脚本文件并编译Lua脚本 globals.loadfile("src/main/assets/test.lua").call(); LuaValue lua1 = globals.get(LuaValue.valueOf("luaFun3")); lua1.call(); }
- 运行测试方法test2输出:
Java + LuaStatic Java +Lua
- Lua与Java运算速度对比
test.lua
function test() a = 0; for i = 0, 1000000, 1 do a = a + i; end return "over";end
JavaTest.java
@Test public void test(){ long l = System.currentTimeMillis(); int a = 0; for (int i = 0; i < 1000000; i++) { a += i; } System.out.println("Java : "+ (System.currentTimeMillis() - l)); Globals globals = JsePlatform.standardGlobals(); //加载Java脚本文件并编译Lua脚本 globals.loadfile("src/main/assets/test.lua").call(); LuaValue lua1 = globals.get(LuaValue.valueOf("test")); l = System.currentTimeMillis(); lua1.call().tostring(); System.out.println("Lua:"+ (System.currentTimeMillis() - l)); }
输出结果:
Java : 7Lua:518
在不加Lua脚本加载的时间,多次测试,大概计算速度相差五十倍左右
LuaJava 这个没找到具体的库~~
Android-Lua GitHub地址:https://github.com/liangchenhe55/Android-Lua
- 引入库:
implementation group: 'com.blakequ.luajava', name: 'luajava', version: '1.0'
- 基本使用方法
- Java调用Lua函数
MainActivity.java
//应用启动之后获取LuaStatemLuaState = LuaStateFactory.newLuaState();mLuaState.openLibs();//通过上下文返回lua脚本mLuaState.LdoString(readAssetsTxt(this, "test.lua"));//加载lua函数mLuaState.getGlobal("luaFun1");//传入参数mLuaState.pushString("lua");//第一个参数表示传入参数个数,第二个表示返回参数个数mLuaState.call(1, 1);//获取返回值mLuaState.toString(-1);
test.lua
function luaFun1(str) return str;end
- Lua中引用Java的方法
Java的方法需要是继承至JavaFunction()
方法的,并重写构造函数和execute()
以及register()
方法-
构造方法用于传入LuaState对象
-
execute()
方法是想传入方法 -
register()
为想生成的Lua函数取名具体实现看后面的实例
-
- Android中Lua应用
- XMl文件配置
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
MyJavaFunction.java (注入Lua脚本中的方法一)
public class MyJavaFunction extends JavaFunction { public MyJavaFunction(LuaState luaState) { super(luaState); } @Override public int execute() { // 获取栈中Lua传入的参数,注意第一个参数固定为上下文环境。 String str = L.toString(2); L.pushString("Java的数据 + Lua的Str:"+str); return 1; // 返回值的个数 } @Override public void register(String name){ try { // 注册为 Lua 全局函数 super.register("testJava"); } catch (Exception e) { e.printStackTrace(); } }}
AsyncJavaFunction.java(注入Lua脚本中的Java方法二)
public class AsyncJavaFunction extends JavaFunction { // lua 回调函数 // lua callback function private LuaObject callbackFun; public AsyncJavaFunction(LuaState L) { super(L); } @Override public int execute() { // 获取Lua传入的参数,注意第一个参数固定为上下文环境。 if (L.isFunction(2)) { callbackFun = L.getLuaObject(2); new MyAsync().execute(); } return 0; } void register() { try { // 注册为 Lua 全局函数 register("http"); } catch (LuaException e) { e.printStackTrace(); } } class MyAsync extends AsyncTask { long t; @Override protected void onPreExecute() { super.onPreExecute(); t = System.currentTimeMillis(); } @Override protected Integer doInBackground(Integer... integers) { try { // 模拟耗时操作(例如网络请求) Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(Integer integer) { super.onPostExecute(integer); if (callbackFun != null) { try { // 2个参数,0 个返回值。 callbackFun.call(new Object[]{"OK", System.currentTimeMillis() - t}, 0); } catch (LuaException e) { e.printStackTrace(); } } } }}
test.lua
function luaFun1(str) return testJava(str);endfunction luaCallback(tv) -- http 函数是由 java `AsyncJavaFunction` 类注入的 -- http function was injected by java `AsyncJavaFunction` http(function(result, time) tv:setText(string.format("result: %s\ntime: %dms", result, time)); end )end
MainActivity.java (主程序文件)
public class MainActivity extends AppCompatActivity { private TextView mTextView; private LuaState mLuaState; private Button mButton; private Button mButton2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //绑定控件 mTextView = findViewById(R.id.textView); mButton = findViewById(R.id.button); mButton2 = findViewById(R.id.button2); //应用启动之后获取LuaState mLuaState = LuaStateFactory.newLuaState(); mLuaState.openLibs(); //通过上下文返回lua脚本 mLuaState.LdoString(readAssetsTxt(this, "test.lua")); mButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //利用Java函数生成lua函数,设置函数名为testJava new MyJavaFunction(mLuaState).register("testJava"); //加载lua函数 mLuaState.getGlobal("luaFun1"); //传入参数 mLuaState.pushString("test"); //第一个参数表示传入参数个数,第二个表示返回参数个数 mLuaState.call(1, 1); mTextView.setText(mLuaState.toString(-1)); } }); mButton2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mTextView.setText("Loading..."); new AsyncJavaFunction(mLuaState).register(); mLuaState.getGlobal("luaCallback"); mLuaState.pushJavaObject(mTextView); mLuaState.call(1, 0); } }); } public static String readAssetsTxt(Context context, String fileName) { try { InputStream is = context.getAssets().open(fileName); int size = is.available(); byte[] buffer = new byte[size]; is.read(buffer); is.close(); String text = new String(buffer, "utf-8"); return text; } catch (IOException e) { e.printStackTrace(); } return "err"; } @Override protected void onDestroy() { //关闭lua栈 mLuaState.close(); super.onDestroy(); }}
更多相关文章
- Android(安卓)NDK开发之JNI基础知识
- 例说 android:mimeType
- Android(安卓)控制ScrollView滚动的实例详解
- android setBackgroundDrawable setImageBitmap 区别
- Android(安卓)Activity间切换动画效果
- android tween 四种动画
- Android(安卓)输入系统(一)InputManagerService
- Android中文API(145) —— NotificationManager
- Android(安卓)Wi-Fi Display(Miracast)介绍