Android 平臺文檔

2018-01-18 12:08 更新

集成說明

  1. 下載源碼到本地
  2. 打開Release目錄,將Android目錄中的LuaScriptCore.jar文件拷貝到項目的libs目錄中,其他的子目錄(如:arm64-v8a、armeabi等)拷貝到j(luò)niLibs目錄中。
  3. 在Android Studio中選中剛添加的LuaScriptCore.jar,右鍵彈出菜單選擇"Add As Library..."。
  4. 打開主模塊的build.gradle配置文件,設(shè)置jniLibs.srcDirs屬性,如下:

    android {
    
        //...
    
        sourceSets {
    
            main {
                jniLibs.srcDirs "jniLibs"
            }
    
        }
    }
    
  5. 成功編譯后則可以正常使用LuaScriptCore了。

關(guān)于重新編譯的問題

  1. 打開Android Studio,然后導(dǎo)入Source/Android/目錄下的項目。
  2. Command + F9 重新編譯目錄。
  3. 編譯成功后,在模塊的build/intermediates/bundles/release目錄可以找到一個classes.jar和jni的文件夾。
  4. 這個jar和jni目錄中的so庫就是LuaScriptCore的庫文件。

使用說明

初始化LuaScriptCore

LuaScriptCore中提供了LuaContext這個上下文對象類來維護整個Lua的環(huán)境,所以使用LuaScriptCore的第一步就是對LuaContext進行初始化。如:

LuaContext context = LuaContext.create(this);

初始化完畢后才能進行下面的各種操作。

解析Lua腳本

原生層中要操作Lua中的變量或者方法,通常使用到的就是組織Lua腳本來進行一些列的Lua操作(LuaScriptCore屏蔽了Lua庫中的C Api,目的是讓代碼更加接近原生,使用起來更加得心應(yīng)手),然后交由Context進行腳本的解析。如:

context.evalScript("print('Hello World');");

注冊一個原生方法給Lua調(diào)用

對于一些耗時或者Lua無法實現(xiàn)的功能(如:手機設(shè)備的拍照),都可以考慮交由原生層來實現(xiàn),然后提供接口讓Lua進行調(diào)用。如下面獲取手機設(shè)備信息的方法:

在Java代碼中定義方法

context.registerMethod("getDeviceInfo", new LuaMethodHandler() {
    @Override
    public LuaValue onExecute(LuaValue[] arguments) {

        HashMap devInfoMap = new HashMap();
        devInfoMap.put("deviceName", Build.DISPLAY);
        devInfoMap.put("deviceModel", Build.MODEL);
        devInfoMap.put("systemName", Build.PRODUCT);
        devInfoMap.put("systemVersion", Build.VERSION.RELEASE);

        return new LuaValue(devInfoMap);
    }
});

在Lua代碼中調(diào)用方法

local tbl = getDeviceInfo();

調(diào)用一個Lua方法

有時候需要通過調(diào)用Lua中的方法來取得返回值(在原生層中只能取得一個返回值),然后再做后續(xù)的處理,例如:

在Lua代碼中有add方法的定義

function add (a, b)

    return a+b;

end

在Java代碼中通過context調(diào)用Lua方法

LuaValue retValue = context.callMethod("add", new LuaValue[]{new LuaValue(100), new LuaValue(924)});
Log.v("luaScriptCore", String.format("%d", retValue.toInteger()));

模塊化擴展

LuaContext所定義的方法都是全局的,有時候需要對一系列的方法進行一個包裝,希望這些方法都歸類在某個模塊下,一來方便根據(jù)模塊來劃分方法的功能,二來可以避免名稱的沖突。因此,可以使用LuaModule來對Lua的功能進行擴展。需要根據(jù)下面步驟實現(xiàn):

  1. 新聲明一個模塊類繼承于LuaModule類(必須繼承于LuaModule類,否則無法進行模塊注冊)
  2. 在創(chuàng)建的模塊類中定義需要導(dǎo)出到lua的類方法(即static修飾的方法),聲明方法完全跟Java聲明方法一樣(對于不想導(dǎo)出到Lua的方法可以在設(shè)置為非public訪問權(quán)限或者以下劃線“_”開頭)。
  3. 調(diào)用LuaContext的registerModule方法將定義的類型傳入即完成功能模塊的擴展。

下面例子定義了一個日志模塊,如:

在Java代碼中定義LuaModule的子類

/**
 * 日志模塊
 * Created by vimfung on 16/9/23.
 */
public class LogModule extends LuaModule
{
    public static String version()
    {
        return "1.0.0";
    }

    public static void writeLog(String message)
    {
        Log.v("luascriptcore", message);
    }
}

注冊模塊

luaContext.registerModule(LogModule.class);

在Lua代碼中調(diào)用

LogModule.writeLog('Hello Lua Module!');

讓Lua面向?qū)ο?/h2>

Lua中沒有明確的面向?qū)ο筇匦裕琇uaScriptCore提供了一個面向?qū)ο蟮臄U展,Lua可以簡單地封裝類型,并且進行類型實例的使用。首先需要先注冊面向?qū)ο蟮哪K類LuaObjectClass(如果原生層有繼承于LuaObjectClass類的子類需要注冊時,該步驟可省略),如:

luaContext.registerModule(LuaObjectClass.class);

注冊成功后,可以直接在Lua中定義類型,如:

Object.subclass("MyClass");

-- 重寫類型的初始化方法
function MyClass:init ()
    print("MyClass instance initialize...");
end

-- 定義類型屬性
MyClass.property = 0;

local instance = MyClass.create();
print (instance.property);

上述代碼的subclass就是子類化對象方法,其接收一個類型名稱參數(shù),調(diào)用后會創(chuàng)建一個對應(yīng)名稱的類型。該類型擁有Object的所有特性。

對于Lua的類定義有如下設(shè)定:

  1. 所有類型的根類是Object,這個注冊LuaObjectClass后會有這個類的定義.
  2. 必須使用subclass方法來進行子類化,必須傳入一個有效并且不重復(fù)的類型名稱參數(shù)。
  3. 必須使用類型的create方法進行類對象的實例化。
  4. 類型中的方法(即類方法)都以.號進行調(diào)用,類實例中的方法都以:號進行調(diào)用。類型和實例的屬性都以.號進行訪問。
  5. 每個類中都有一個叫super的屬性來指代其父類型。
  6. 需要調(diào)用父類方法時,請使用"類型.super:method"方式進行調(diào)用,如:MyClass.super:test();
  7. 當類實例對象初始化時會觸發(fā)init方法,銷毀時會觸發(fā)destroy方法,可以通過重寫這些方法來進行一些額外的工作。

如果需要讓原生類直接映射到Lua中,按照下面步驟實現(xiàn):

  1. 定義一個新的類繼承于LuaObjectClass類。
  2. 定義新類型的屬性和方法(注:原生類中的public訪問權(quán)限的屬性會轉(zhuǎn)換為Lua類中的setXXX和XXX方法),對于不想導(dǎo)出到Lua中的方法或?qū)傩钥梢栽诼暶鲿r使用非public訪問權(quán)限或以下劃線"_"開頭。
  3. 定義類的類方法會導(dǎo)出給類型,定義實例方法會導(dǎo)出給類型的實例
  4. 調(diào)用LuaContext的registerModule方法將定義的類型傳入即完成Lua類的聲明。導(dǎo)入時可以直接導(dǎo)入子類,LuaContext會檢測是否有導(dǎo)入根類型。

如在Java中有如下類型定義:

public class Person extends LuaObjectClass
{
    public String name;

    public void speak()
    {
        Log.v("luascriptcore", String.format("%s speak", name));
    }

    public void walk()
    {
        Log.v("luascriptcore", String.format("%s walk", name));
    }

    public static void printPersonName (Person person)
    {
        NSLog(@"Person name = %@", person.name);
    }

    public Person(LuaContext context)
    {
        super(context);
    };
}

然后對該類型進行注冊:

_luaContext.registerModule(Person.class);

注冊成功后,在lua中即可使用該類型:

local person = Person.create();
person:setName("vimfung");
person:walk();
person:speak();
Person.printPersonName(person);

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號