做移動端開發,最蛋疼的就是不能動態發版,不能像 web 那樣發版立即全部使用者生效,然而 lua語言 為其提供了可能性。lua
是一種指令碼語言,使用 lua 來構建跨平臺原生應用有許多好處,比如 lua 語言簡潔高效,可移植性好, Lua虛擬機器極為輕量,僅佔用200到300k的記憶體空間,且速度極快。
演示
寫一個簡單的程式碼演示一下。新建一個 lua 檔案,叫做 view.lua
, 放在手機的 sdcard 上,檔案目錄為 /sdcard/view.lua
require "import"
import "android.widget.*"
import "android.content.*"
function getView()
local layout = {
LinearLayout,
orientation = "vertical",
layout_width = "fill",
layout_height = "fill",
{
Button,
id = "btn",
layout_marginTop="8dp",
layout_width = "fill",
layout_height = "50dp",
text = "click"
},
}
local view = loadlayout(layout)
return view
end
複製程式碼
執行一下,
螢幕中上半部分是 Android 的 xml 佈局中寫好的程式碼,當點選執行按鈕時,載入 lua 指令碼,返回一個 View 物件,然後新增到佈局中。一個簡單的 lua 指令碼編寫的檢視就寫好了。 接下來修改一下,設定個點選事件。
require "import"
import "android.widget.*"
import "android.content.*"
function getView()
local layout = {
LinearLayout,
orientation = "vertical",
layout_width = "fill",
layout_height = "fill",
{
Button,
id = "btn",
layout_marginTop="8dp",
layout_width = "fill",
layout_height = "50dp",
text = "click"
},
}
local ids = {} -- store ids to find view
local view = loadlayout(layout, ids)
ids.btn.onClick = function()
Toast.makeText(activity,"2333",0).show()
end
return view
end
複製程式碼
執行效果
再來個稍微複雜點的例子,寫個列表,新建 list.lua
檔案,放在手機的 sdcard/list.lua
require "import"
import "android.widget.*"
import "android.content.*"
import "android.view.View"
import "androlua.LuaHttp"
import "androlua.LuaAdapter"
import "androlua.LuaImageLoader"
local JSON = require("cjson")
local uihelper = require('uihelper')
-- create view table
local layout = {
LinearLayout,
orientation = "vertical",
layout_width = "fill",
layout_height = "fill",
{
ListView,
id = "listview",
dividerHeight = 0,
layout_width = "fill",
layout_height = "fill",
},
}
local item_view = {
FrameLayout,
layout_width = "fill",
layout_height = "240dp",
{
ImageView,
id = "iv_image",
layout_width = "fill",
layout_height = "fill",
scaleType = "centerCrop",
},
{
TextView,
id = "tv_title",
background = "#66000000",
layout_width = "fill",
layout_height = "fill",
padding = "32dp",
gravity = "center",
maxLines = "5",
lineSpacingMultiplier = '1.2',
textSize = "14sp",
textColor = "#CCFFFFFF",
},
}
local data = {
dailyList = {}
}
local adapter
local function getData()
-- http://baobab.kaiyanapp.com/api/v1/feed
local url = data.nextPageUrl
if url == nil then url = 'http://baobab.kaiyanapp.com/api/v1/feed?udid=3e7ee30c6fc0004a773dc33b0597b5732b145c04' end
if url:find('udid=') == nil then url = url .. '&udid=3e7ee30c6fc0004a773dc33b0597b5732b145c04' end
print(url)
LuaHttp.request({ url = url }, function(error, code, body)
if error or code ~= 200 then
print('fetch data error')
return
end
local str = JSON.decode(body)
uihelper.runOnUiThread(activity, function()
data.nextPageUrl = str.nextPageUrl
local list = str.dailyList[1].videoList
for i = 1, #list do
data.dailyList[#data.dailyList + 1] = list[i]
end
adapter.notifyDataSetChanged()
end)
end)
end
local function launchDetail(item)
Toast.makeText(activity, item.title, 0).show()
end
function getView()
local view = loadlayout(layout)
adapter = LuaAdapter(luajava.createProxy("androlua.LuaAdapter$AdapterCreator", {
getCount = function() return #data.dailyList end,
getItem = function(position) return nil end,
getItemId = function(position) return position end,
getView = function(position, convertView, parent)
position = position + 1 -- lua 索引從 1開始
if position == #data.dailyList then
getData()
end
if convertView == nil then
local views = {} -- store views
convertView = loadlayout(item_view, views, ListView)
if parent then
local params = convertView.getLayoutParams()
params.width = parent.getWidth()
end
convertView.setTag(views)
end
local views = convertView.getTag()
local item = data.dailyList[position]
if item then
LuaImageLoader.load(views.iv_image, item.coverForFeed)
views.tv_title.setText(item.title)
end
return convertView
end
}))
listview.setAdapter(adapter)
listview.setOnItemClickListener(luajava.createProxy("android.widget.AdapterView$OnItemClickListener", {
onItemClick = function(adapter, view, position, id)
launchDetail(data.dailyList[position + 1])
end,
}))
getData()
return view
end
複製程式碼
建立 listView , 設定 adapter ,網路請求,重新整理列表。看下效果吧。
程式碼放到了 github ? 原始碼
原理圖
寫了幾篇文章比較詳細的介紹了原理,想了解的可以看一下
支援 iOS 嗎?
Lua 是用 c 語言開發的,可移植性比較好,想支援 iOS 的話,原理時一樣的,不過參考目前已有的跨平臺技術。關於跨平臺方面的一些個人見解,目前已有的跨平臺技術每當涉及到不同平臺的特性時,事情就比較蛋疼了,需要單獨去適配,還有建立一堆連線庫,比如選取本地圖片,不同平臺的資料庫,平臺特有 api,真是一份程式碼到處執行終是夢,一份兒程式碼到處採坑才是真。
Android 開發能支援到什麼程度?
看到了上面的原理圖就可以知道,支援 Android SDK 幾乎所有的 API。
聯絡我
- github:hanks-zyh
- weibo: @D藍小魚
- twitter: hanks
- email: zhangyuhan2014@gmail.com