Android 调用 Lua /Lua 调用 Android 代码
在Android项目中使用Lua,需要两个步骤:
1、加载Lua脚本解析引擎。
2、以Native API方式调用引擎接口
直接以JNI方式调用Lua解析引擎的接口十分麻烦,开源项目LuaJava(https://github.com/mkottman/AndroLua )对这些JNI接口进行了很好的封装,它是一个包含了LuaJava的Android平台的Lua解析器,它提供一系列映射到Lua C实现函数的Java接口。
1.获取LuaJava 工程,引入到你的Eclipse中,并将其设为Library工程
2.将Lua解析器相关的C代码和 LuaJava的C代码打包成so文件
3.创建你demo工程,并引入LuaJava工程
a.布局文件:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="10dp" android:orientation="vertical" > <Button android:id="@+id/executeLuaStatemanet" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="15dp" android:text="运行Lua脚本语句" /> <Button android:id="@+id/executeLuaFile" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="15dp" android:text="运行Lua脚本文件" /> <Button android:id="@+id/callAndroidApi" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="15dp" android:text="调用 Android API" /> <TextView android:id="@+id/displayResult1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dp"/> <TextView android:id="@+id/displayResult2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dp"/> <LinearLayout android:id="@+id/layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:orientation="vertical"> </LinearLayout> </LinearLayout> <Button android:id="@+id/clearBtn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:layout_margin="15dp" android:text="清除结果" /> </RelativeLayout>
package com.open.lua; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import org.keplerproject.luajava.LuaState; import org.keplerproject.luajava.LuaStateFactory; import com.example.androidluatest.R; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.LinearLayout; import android.widget.TextView; public class MainActivity extends Activity { private LuaState mLuaState;//Lua解析和执行由此对象完成 private TextView displayResult1;//用于演示,显示数据 private TextView displayResult2; private LinearLayout mLayout; private static int count; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); displayResult1 = (TextView)findViewById(R.id.displayResult1); displayResult2 = (TextView)findViewById(R.id.displayResult2); mLayout = (LinearLayout) findViewById(R.id.layout); findViewById(R.id.executeLuaStatemanet).setOnClickListener(listener); findViewById(R.id.executeLuaFile).setOnClickListener(listener); findViewById(R.id.callAndroidApi).setOnClickListener(listener); findViewById(R.id.clearBtn).setOnClickListener(listener); mLuaState = LuaStateFactory.newLuaState(); mLuaState.openLibs(); } private OnClickListener listener=new OnClickListener() { @Override public void onClick(View v) { switch(v.getId()) { case R.id.executeLuaStatemanet: executeLuaStatemanet(); break; case R.id.executeLuaFile: executeLuaFile(); break; case R.id.callAndroidApi: callAndroidAPI(); break; case R.id.clearBtn: displayResult1.setText(""); displayResult2.setText(""); mLayout.removeAllViews(); break; } } }; private void executeLuaStatemanet() { mLuaState.LdoString(" varSay = 'This is string in lua script statement.'");// 定义一个Lua变量 mLuaState.getGlobal("varSay");// 获取 displayResult1.setText(mLuaState.toString(-1));// 输出 } private void executeLuaFile() { mLuaState.LdoString(readStream(getResources().openRawResource(R.raw.luafile))); mLuaState.getField(LuaState.LUA_GLOBALSINDEX, "functionInLuaFile");// 找到functionInLuaFile函数 mLuaState.pushString("从Java中传递的参数");// 将参数压入栈 // functionInLuaFile函数有一个参数,一个返回结果 int paramCount = 1; int resultCount = 1; mLuaState.call(paramCount, resultCount); mLuaState.setField(LuaState.LUA_GLOBALSINDEX, "resultKey");// 将结果保存到resultKey中 mLuaState.getGlobal("resultKey");// 获取 displayResult2.setText(mLuaState.toString(-1));// 输出 } private void callAndroidAPI() { mLuaState.LdoString(readStream(getResources().openRawResource(R.raw.luafile))); mLuaState.getField(LuaState.LUA_GLOBALSINDEX, "callAndroidApi");// 找到functionInLuaFile函数 mLuaState.pushJavaObject(getApplicationContext()); mLuaState.pushJavaObject(mLayout); mLuaState.pushString("lua调用 android , TextView的数据:"+(++count)); mLuaState.call(3, 0); } private String readStream(InputStream is) { try { ByteArrayOutputStream bo = new ByteArrayOutputStream(); int i = is.read(); while (i != -1) { bo.write(i); i = is.read(); } return bo.toString(); } catch (IOException e) { Log.e("ReadStream", "读取文件流失败"); return ""; } } }
function functionInLuaFile(key) return ' Function in Lua file . Return : '..key..'!' end function callAndroidApi(context,layout,tip) tv = luajava.newInstance("android.widget.TextView",context) tv:setText(tip) layout:addView(tv) end
d.效果图
demo工程:http://download.csdn.net/detail/zz7zz7zz/6584175
参考文章:http://my.oschina.net/chenyoca/blog/69169