在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.布局文件:
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:orientation="vertical" >
android:id="@+id/executeLuaStatemanet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:text="运行Lua脚本语句" />
android:id="@+id/executeLuaFile"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:text="运行Lua脚本文件" />
android:id="@+id/callAndroidApi"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:text="调用 Android API" />
android:id="@+id/displayResult1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"/>
android:id="@+id/displayResult2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"/>
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:orientation="vertical">
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="清除结果" />
b. Activity 代码
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 "";
}
}
}
c. 位于raw目录下的Lua文件代码
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工程:
具体下载目录在 /2014年资料/2月/11日/Lua 学习教程之Android与Lua相互调用