app發版成本高,覆蓋速度慢,覆蓋率頁低。一些策略上的東西若是可以從服務端控制會方便一些。
因此考慮使用Lua這種嵌入式語言做爲策略實現,Java則是宿主語言。html
整體上看是一個模板方法模式。Lua提供模板方法,其中須要的一些具體實現則有宿主語言Java提供。java
可以做爲Java與Lua進行通訊的橋樑工具還有別的一些。
可是Luaj 是用純Java實現,客戶端容易加載。且目前還一直有更新和維護,相對感受靠譜。閉包
須要注意的是: 新版的LuaJ3.0是針對Lua5.2開發的,對Lua5.1會有不兼容的部分(例如module函數不能用了)
若是使用Lua5.1,則能夠使用LuaJ2.0.3app
更詳細的介紹函數
這個簡單,下載LuaJ2.0.3版,解壓,加載lib/luaj-jse-2.0.3.jar
lib/裏邊還有個jme,這個是針對j2me環境的。工具
功能
實現一個生成時間相關的參數的功能
value = (int)(timestamp / 1000 ) ^ (int)(timestamp / 400)
^ 符號表示按位異或。ui
其中:
– 整個式子的計算流程由lua提供模板方法
– 除法後取整的功能由lua以module方式提供
– lua沒有原生的位操做,因此這部分由java提供
– lua原生的os.time()依賴系統,因而timestamp方法由java提供,生成秒級時間戳lua
文件目錄說明spa
1
2
3
4
5
6
7
8
9
10
11
|
.
|-- lua
| |-- gen.lua 主流程文件
| `-- tool
| `-- div.lua 提供除法
`-- src
|-- app
| `-- Calc.java java的入口程序
`-- lualib
`-- Math.java java提供的異或方法,和時間戳方法
|
接下來就看4個文件的具體代碼吧。請着重注意註釋,要說的都在裏邊了
Calc.java:code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
package app;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.lib.jse.JsePlatform;
public class Calc {
public static void main(String[] args) {
long key = getKey();
System.out.println(key);
System.out.println(getKeyJava());
}
public static long getKey() {
//獲取一個lua的運行環境,lua虛擬機應該就在這裏了
//lua是個弱類型語言,在java裏,全部從lua得到的,或者要傳遞給lua的,都是LuaValue對象
LuaValue _G = JsePlatform.standardGlobals();
//執行gen.lua腳本
//_G.get("dofile")獲取dofile方法的對象
//get實際上是獲取table值的方法,dofile就是全局table的一個值
//對於Function類型的對象能夠用call方法去調用,參數就是lua方法須要的參數,可是必定要轉換成LuaValue類型
_G.get("dofile").call(LuaValue.valueOf("lua/gen.lua"));
//上一句執行完之後,gen.lua中的genkey函數就在全局變量中了,
//能夠這樣直接調用
LuaValue key = _G.get("genkey").call();
return key.checklong();
}
//用java實現的,比較用
//value = (int)(timestamp / 1000 ) ^ (int)(timestamp / 400)
public static long getKeyJava() {
long tm = System.currentTimeMillis() / 1000;
return (tm / 1000) ^ (tm / 400);
}
}
|
Math.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
package lualib;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.lib.OneArgFunction;
import org.luaj.vm2.lib.TwoArgFunction;
import org.luaj.vm2.lib.ZeroArgFunction;
//luaj提供了一些方法模板 ZeroArgFunction OneArgFunction等
//具體能夠看那個詳細介紹
public class Math extends OneArgFunction {
//lua的方法都是閉包,在java中必定是用類對象與之對應的。
//因而call這個方法就是調用閉包使用所調用的方法,必須實現
public LuaValue call(LuaValue modname) {
//這是類在lua裏是一個模塊,也就是個函數包,在lua裏也就是一個table
//table的每個元素是一個函數(閉包而已)
//這個lib就是一個table,用來存放各個lua模塊方法
LuaValue lib = tableOf();
//設置timestamp方法
lib.set("timestamp", new lua_timestamp());
//設置異或方法
lib.set("bitxor", new lua_bitxor());
//這裏不肯定:env是該類的環境參數,暫時沒研究這一句的做用,本例中不設置也不要緊
//env.set(modname.checkjstring(), lib);
return lib;
}
static class lua_timestamp extends ZeroArgFunction {
public LuaValue call() {
return LuaValue.valueOf(System.currentTimeMillis() / 1000);
}
}
static class lua_bitxor extends TwoArgFunction {
public LuaValue call(LuaValue a, LuaValue b) {
//lua傳進來參數都是LuaValue的,java使用的時候須要使用相應的check方法轉爲本地變量
long pa = a.checklong();
long pb = b.checklong();
long r = pa ^ pb;
//返回的時候須要用valueOf方法轉爲LuaValue類型
return LuaValue.valueOf(r);
}
}
}
|
lua程序就簡單多了
gen.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
|
--注意查找目錄是從工程的根目錄開始的
div = require ("lua.tool.div")
--引用java提供的方法,則直接寫java的類名就好
jlib = require ("lualib.Math")
-- 模板方法
function genkey()
tm = jlib.timestamp()
a = div.div(tm, 1000)
b = div.div(tm, 400)
r = jlib.bitxor(a, b)
return r
end
|
div.lua
1
2
3
4
5
6
|
module(..., package.seeall)
-- 這裏也能夠require java提供的模塊,本例沒用到
function div(a, b)
return math.floor(a / b)
end
|
整體上來講調用起來還算容易,只是文檔有些缺少。
若是要用Lua5.2則必須用LuaJ3.0。LuaJ3.0和2.0.3仍是有一些不同的,能夠參考前文提到的詳細介紹。
http://levelup.sinaapp.com/