lua 调用android方法,android下调用lua脚本方法

在android里使用lua的文章网上已经有很多,这里就不具体说了。但网上大多数的例子只是简单的在java里调用了LdoString,很少有提到如何加载lua脚本文件。所以,这里主要说一下如何直接调用lua脚本文件的方法。我在网上查找到的方法以及自己研究后的结果整理如下:

lua脚本是文本文件,为了不让android将其编译成二进制的形式,一般将其放到res/raw下面或者assets下面。但在android里所有这些资源都是在apk包里的(本人经验不是很多,这是我目前所以理解的),所以不能够直接通过文件路径的方法访问,于是luajava的LdoFile也无法正常加载lua文件。那么只好通过变通的方式执行lua脚本了。

假设我们的lua文件为/res/raw/hello.lua(放在assets下也是同样的道理)

一、利用流读取lua脚本的内容并将其赋值给String变量,通过LdoString执行。

网上有类似的方法,整理如下:

Java代码38022573_1.pngL.LdoString(readStream(getResources().openRawResource(R.raw.hello)));

其中getResources().openRawResource(R.raw.hello))返回的是hello.lua的文件流。

readStream是读取全部文件内容,并以String的类型返回,代码如下

Java代码38022573_1.pngprivateString readStream(InputStream is) {

try{

ByteArrayOutputStream bo = newByteArrayOutputStream();

inti = is.read();

while(i != -1) {

bo.write(i);

i = is.read();

}

returnbo.toString();

} catch(IOException e) {

Log.e("ReadStream","读取文件流失败");

return"";

}

}

这样就可以通过LdoString的方式执行lua脚本了。

二、将lua脚本复制到files文件夹下,再执行LdoFile

该方法主要是将apk中的lua文件复制出来,以便让程序能够通过文件路径的方式访问到脚本,进而可以执行LdoFile方法。

Java代码38022573_1.pngprivatevoidcopyResourcesToLocal() {

String name, sFileName;

InputStream content;

R.raw a = newR.raw();

java.lang.reflect.Field[] t = R.raw.class.getFields();

Resources resources = getResources();

for(inti =0; i 

FileOutputStream fs = null;

try{

name = resources.getText(t[i].getInt(a)).toString();

sFileName = name.substring(name.lastIndexOf('/') +1, name

.length());

content = getResources().openRawResource(t[i].getInt(a));

// Copies script to internal memory only if changes were made

sFileName = getApplicationContext().getFilesDir() + "/"

+ sFileName;

Log.d("Copy Raw File","Copying from stream "+ sFileName);

content.reset();

intbytesum =0;

intbyteread =0;

fs = newFileOutputStream(sFileName);

byte[] buffer =newbyte[1024];

while((byteread = content.read(buffer)) != -1) {

bytesum += byteread; // 字节数 文件大小

System.out.println(bytesum);

fs.write(buffer, 0, byteread);

}

fs.close();

} catch(Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

copyResourcesToLocal的作用是复制lua文件。这是我在ScriptForAndroidTemplate工程看到的,它的方法就是将脚本文件直接复制到脚本解释器的目录下。

当然,这里我没有判断lua文件是否已经存在以及文件是否有变化,真正的程序里最好加上判断,当真的需要复制文件时再进行复制。

copyResourcesToLocal方法需要放在执行luajava的方法的前面,可以是onCreate开始的位置。之后就可以调用luajava的LdoFile方法了

Java代码38022573_1.pngL.LdoFile(getApplicationContext().getFilesDir() +"/"+"hello.lua");

下面贴一个本身测试用的完整的Activity

Java代码38022573_1.pngpackagehelloandroid.test;

importjava.io.ByteArrayOutputStream;

importjava.io.FileOutputStream;

importjava.io.IOException;

importjava.io.InputStream;

importandroid.app.Activity;

importandroid.content.res.Resources;

importandroid.os.Bundle;

importandroid.widget.TextView;

importandroid.util.Log;

importorg.keplerproject.luajava.*;

publicclassHelloandroidextendsActivity {

@Override

protectedvoidonStart() {

// TODO Auto-generated method stub

super.onStart();

copyResourcesToLocal();

}

/** Called when the activity is first created. */

@Override

publicvoidonCreate(Bundle savedInstanceState) {

LuaState L = LuaStateFactory.newLuaState();

System.out.println("Lua:newLuaState");

L.openLibs();

System.out.println("Lua:openLibs");

try{

L.pushObjectValue(Log.class);

L.setGlobal("Log");

} catch(LuaException e1) {

// TODO Auto-generated catch block

e1.printStackTrace();

}

// String lua = this.getClass().getResource("").getPath();

System.out.println("Lua script: "

+ getResources().getString(R.raw.hello));

System.out.println("path: "

+ getApplicationContext().getPackageCodePath() + "/"

+ getResources().getText(R.raw.hello).toString());

intluaerr = L.LdoFile(getApplicationContext().getFilesDir() +"/"

+ "hello.lua");

// System.out.println("Lua:LdoString");

// getResources().getResourceName(R.raw.hello);

// int luaerr =

// L.LdoString(readStream(getResources().openRawResource(R.raw.hello)));

System.out.println("Lua:LdoFile error "+ luaerr);

L.getGlobal("text");

System.out.println("Lua:getGlobal");

String text = "default content";

text = L.toString(-1);

L.getGlobal("chinese");

text += L.toString(-1);

// L.pop(2);

super.onCreate(savedInstanceState);

TextView tv = newTextView(this);

tv.setText(text);

L.getGlobal("setcontent");

try{

L.pushObjectValue(tv);

} catch(LuaException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

L.pcall(1,0,0);

setContentView(tv);

}

/**

* 读取输入流的全部字节,并以String形式返回

*

* @param is

* @return

*/

privateString readStream(InputStream is) {

try{

ByteArrayOutputStream bo = newByteArrayOutputStream();

inti = is.read();

while(i != -1) {

bo.write(i);

i = is.read();

}

returnbo.toString();

} catch(IOException e) {

Log.e("ReadStream","读取文件流失败");

return"";

}

}

/**

* 将/res/raw下面的资源复制到 /data/data/applicaton.package.name/files

*/

privatevoidcopyResourcesToLocal() {

String name, sFileName;

InputStream content;

R.raw a = newR.raw();

java.lang.reflect.Field[] t = R.raw.class.getFields();

Resources resources = getResources();

for(inti =0; i 

FileOutputStream fs = null;

try{

name = resources.getText(t[i].getInt(a)).toString();

sFileName = name.substring(name.lastIndexOf('/') +1, name

.length());

content = getResources().openRawResource(t[i].getInt(a));

// Copies script to internal memory only if changes were made

sFileName = getApplicationContext().getFilesDir() + "/"

+ sFileName;

Log.d("Copy Raw File","Copying from stream "+ sFileName);

content.reset();

intbytesum =0;

intbyteread =0;

fs = newFileOutputStream(sFileName);

byte[] buffer =newbyte[1024];

while((byteread = content.read(buffer)) != -1) {

bytesum += byteread; // 字节数 文件大小

System.out.println(bytesum);

fs.write(buffer, 0, byteread);

}

fs.close();

} catch(Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

}

hello.lua脚本的内容为:

Lua代码38022573_1.pngtext="I am in lua Script\n"

chinese="我是中文,娃哈哈 "

function setcontent(view)

view:setText(text..chinese.."\nthis is setcontent")

Log:i("LuaLog","over setcontent")

end

print "end of lua script"

以上就是本人总结的方法,恳请各位拍砖