本节将全面讲解Lua模块化开发、包管理机制以及在Android平台下的特殊应用场景和优化技巧。
-- 文件: mymodule.lua
local M = {} -- 模块表
-- 公有函数
function M.sayHello(name)
print("Hello, "..(name or "Lua"))
end
-- 私有函数
local function privateFunc()
print("内部实现")
end
return M -- 返回模块表
-- 加载模块
local mymodule = require("mymodule")
-- 使用模块函数
mymodule.sayHello("Android")
-- 自定义加载路径
package.path = package.path .. ";/sdcard/lua/?.lua"
注意: Android中建议将模块放在assets目录,通过修改package.path加载
-- 1. 检查package.loaded缓存
-- 2. 按package.path路径查找文件
-- 3. 按package.cpath查找C模块
-- 4. 调用loader加载模块
-- 5. 结果存入package.loaded
-- 从Android assets加载
table.insert(package.loaders, 2, function(modname)
local assetFile = "lua/"..modname:gsub("%.", "/")..".lua"
local content = android.loadAsset(assetFile)
if content then
return load(content, "="..modname)
end
end)
-- 使用示例
require("com.example.mymodule")
# 安装LuaRocks
luarocks install luasocket
-- 代码中使用
local socket = require("socket")
-- 预编译库放入assets
local function loadLibrary(name)
local soPath = android.extractAsset("lib"..name..".so")
package.cpath = package.cpath .. ";" .. soPath.."/?.so"
return require(name)
end
-- 加载C模块
local mylib = loadLibrary("mylib")
-- 文件: class.lua
local Class = {}
function Class:new(o)
o = o or {}
setmetatable(o, self)
self.__index = self
return o
end
return Class
-- 使用示例
local Rectangle = require("class")
function Rectangle:area()
return self.width * self.height
end
-- 继承基类
local Square = require("class"):new()
function Square:new(side)
local o = Rectangle:new{width=side, height=side}
setmetatable(o, self)
self.__index = self
return o
end
-- 热加载模块
function hotReload(moduleName)
package.loaded[moduleName] = nil
return require(moduleName)
end
-- 从网络更新模块
local newModule = downloadModule("mymodule.lua")
local func, err = load(newModule, "mymodule")
if func then
package.loaded["mymodule"] = func()
end
-- 业务模块划分
local App = {
network = require("lib.network"),
ui = require("ui.main"),
utils = require("utils")
}
-- 启动应用
function App:run()
self.ui.init()
self.network.start()
end
return App
-- 预加载常用模块
local function preloadModules()
require("json")
require("socket")
require("ui.templates")
end
-- 减少运行时加载开销
-- 按需加载模块
local LazyLoader = {}
function LazyLoader.load(moduleName)
return setmetatable({}, {
__index = function(_, key)
local mod = require(moduleName)
LazyLoader[moduleName] = mod
return mod[key]
end
})
end
-- 使用示例
local heavyModule = LazyLoader.load("heavy.module")
-- 打印模块依赖树
function printDeps(modname, level)
level = level or 0
local indent = string.rep(" ", level)
print(indent..modname)
if package.loaded[modname] then
local info = debug.getinfo(package.loaders[1](modname))
for line in io.lines(info.source:sub(2)) do
local dep = line:match("require%(\"([%w.]+)\"%)")
if dep then printDeps(dep, level + 1) end
end
end
end
-- 测试模块示例
local test = require("test")
function test.mymodule()
local mymodule = require("mymodule")
assert(mymodule.add(1,2) == 3)
end
return test