exapp 扩展应用管理库
作者:江访 | 最后修改:2026-05-13
一、概述
exapp 是扩展应用管理库,为 LuatOS 应用市场体系提供应用沙箱环境和云端数据操作能力。对外接口分为两类:
- 后装应用使用接口:
从应用市场下载的应用在沙箱中直接调用,无需
require,直接调用exapp接口即可。 - 出厂应用使用接口:
出厂应用(如应用商店)通过
exapp = require("exapp")加载后调用exapp接口,包含应用安装/卸载/更新、应用列表管理、IOT 登录登出等。
1.1 适用场景
- 后装应用使用接口适用于从应用市场下载后运行的应用
- 出厂应用使用接口适用于内置的应用商店、设置等系统级应用
二、核心示例
以下示例演示完整的 新建 → 查询 → 删除 → 查询 流程。
id由服务端自动分配,通过list_record查询时返回在records[i].id中。 所有操作通过callback回调获取结果,无需订阅内部消息。
-- 获取登录状态
local info = exapp.iot_get_account_info()
if info.is_guest then
log.warn("请先登录IOT账号")
return
end
-- 步骤1: 新建一条数据
exapp.add_record({cls = 2, uni_key = info.account, i1 = 100, s1 = info.nickname},
function(success, result)
if not success then
log.warn("新建失败", result)
return
end
log.info("新建成功, 开始查询列表...")
-- 步骤2: 查询列表获取记录 id
exapp.list_record({cls = 2, sort = "i1 desc", size = 20},
function(success2, data)
if success2 and data and data.records and #data.records > 0 then
-- 打印所有记录
for i, rec in ipairs(data.records) do
log.info("记录" .. i, "id=" .. rec.id, "i1=" .. rec.i1)
end
-- 步骤3: 通过 id 删除第一条记录
local first_id = data.records[1].id
exapp.delete_record({cls = 2, id = first_id},
function(success3, result3)
if success3 then
log.info("删除成功, 再次查询验证...")
-- 步骤4: 再次查询验证删除结果
exapp.list_record({cls = 2, sort = "i1 desc", size = 20},
function(_, data4)
if data4 and data4.total then
log.info("当前总数:", data4.total)
end
end)
else
log.warn("删除失败", result3)
end
end)
end
end)
end)
三、常量详解
扩展库常量,本扩展库中没有常量。
四、函数详解
4.1 后装应用使用接口
后装应用在沙箱中通过 exapp 直接调用以下接口,无需 require。
4.1.1 接口概览
| 接口名称 | 功能描述 |
| exapp.add_record(params[, callback]) | 添加一条数据记录。所有字段(s1-s4/i1-i4/d1-d2)始终发送,未传时使用默认值。结果通过 callback 回调返回。 |
| exapp.list_record(params[, callback]) | 查询记录列表,支持分页、排序、条件过滤(filter)和仅查当前设备数据(is_me)。结果通过 callback 回调返回。 |
| exapp.delete_record(params[, callback]) | 删除记录(通过 id)。id 来自 list_record 返回结果。结果通过 callback 回调返回。 |
| exapp.iot_get_account_info() | 获取当前 IOT 账号信息。 |
4.1.2 exapp.add_record(params[, callback])
功能
添加一条数据记录。所有 s1-s4/i1-i4/d1-d2 字段始终发送,未传时使用默认值。
参数
params
参数含义:记录参数表
数据类型:table
是否必选:是
注意事项:所有通信/鉴权/加密由 exapp 底层自动处理
参数示例:{cls = 2, uni_key = "user_001", i1 = 100, s1 = "玩家A"}
示例代码:params = {cls = 2, uni_key = "user_001", i1 = 100, s1 = "玩家A"}
取值范围:包含 cls、uni_key、s1-s4、i1-i4、d1-d2 子参数,如下:
{
参数含义:业务分类标记
数据类型:int
取值范围:由开发者自定义的正整数
是否必选:是
注意事项:不同 cls 的数据互不干扰
参数示例:2
示例代码:cls = 2
cls = ,
参数含义:业务主键
数据类型:string
取值范围:最长 64 字符
是否必选:否
注意事项:唯一标识一条记录,不传时为时间戳
参数示例:"user_001"
示例代码:uni_key = "user_001"
uni_key = ,
参数含义:字符串字段(如昵称、名称、描述等)
数据类型:string
取值范围:最长 255 字符
是否必选:否
注意事项:不传默认为空字符串 "",始终随请求发送
参数示例:"玩家A"
示例代码:s1 = "玩家A"
s1 = ,
参数含义:字符串字段
数据类型:string
取值范围:最长 255 字符
是否必选:否
注意事项:不传默认为空字符串 ""
参数示例:""
s2 = ,
参数含义:字符串字段
数据类型:string
取值范围:最长 255 字符
是否必选:否
注意事项:不传默认为空字符串 ""
参数示例:""
s3 = ,
参数含义:字符串字段
数据类型:string
取值范围:最长 255 字符
是否必选:否
注意事项:不传默认为空字符串 ""
参数示例:""
s4 = ,
参数含义:整数字段(如积分、数量、等级等)
数据类型:uint
取值范围:无符号整数
是否必选:否
注意事项:不传默认为 0,始终随请求发送
参数示例:100
示例代码:i1 = 100
i1 = ,
参数含义:整数字段
数据类型:uint
取值范围:无符号整数
是否必选:否
注意事项:不传默认为 0
参数示例:50
i2 = ,
参数含义:整数字段
数据类型:uint
取值范围:无符号整数
是否必选:否
注意事项:不传默认为 0
参数示例:0
i3 = ,
参数含义:整数字段
数据类型:uint
取值范围:无符号整数
是否必选:否
注意事项:不传默认为 0
参数示例:0
i4 = ,
参数含义:时间戳字段
数据类型:int(ts)
取值范围:Unix 时间戳
是否必选:否
注意事项:不传默认为 null,始终随请求发送
参数示例:1759161153
示例代码:d1 = 1759161153
d1 = ,
参数含义:时间戳字段
数据类型:int(ts)
取值范围:Unix 时间戳
是否必选:否
注意事项:不传默认为 null
参数示例:null
d2 = ,
}
callback
参数含义:结果回调函数
数据类型:function
是否必选:否
注意事项:function(success, result) end,success 为 true 表示成功,result 为服务端返回信息
示例代码:add_callback = function(success, result) log.info("result", success, result) end
返回值
操作结果通过 callback 函数异步回调:callback(success, result),success 为 true 表示成功,result 为服务端返回信息。
示例
-- 无回调用法
exapp.add_record({cls = 2, uni_key = "user_001", i1 = 100, s1 = "玩家A"})
-- 带回调用法
exapp.add_record({cls = 2, uni_key = "user_001", i1 = 100, s1 = "玩家A"},
function(success, result)
if success then
log.info("新建成功")
else
log.warn("新建失败", result)
end
end)
-- 不传 uni_key,每次调用都新增(适合日志类数据)
exapp.add_record({cls = 3, i1 = 50, s1 = "每日签到", d1 = os.time()})
4.1.3 exapp.list_record(params[, callback])
功能
按条件查询记录列表,支持分页、排序和条件过滤。
参数
params
参数含义:查询参数表
数据类型:table
是否必选:是
注意事项:结果通过 callback 异步返回,callback(data) 的 data.records 为记录数组,每条含 id、uni_key、s1-s4、i1-i4、d1-d2
参数示例:{cls = 2, sort = "i1 desc", size = 20, is_me = true}
示例代码:params = {cls = 2, sort = "i1 desc", size = 20, is_me = true}
取值范围:包含 cls、uni_key、page、size、sort、desc、is_me、filter 子参数,如下:
{
参数含义:业务分类标记
数据类型:int
取值范围:由开发者自定义的正整数
是否必选:是
注意事项:同 add 接口
参数示例:2
示例代码:cls = 2
cls = ,
参数含义:唯一键
数据类型:string
取值范围:最长 64 字符
是否必选:否
注意事项:用于精确匹配单条记录
参数示例:"user_001"
示例代码:uni_key = "user_001"
uni_key = ,
参数含义:分页偏移
数据类型:int
取值范围:从 1 开始的正整数
是否必选:否
注意事项:默认 1
参数示例:1
示例代码:page = 1
page = ,
参数含义:每页条数
数据类型:int
取值范围:正整数,最大 100
是否必选:否
注意事项:默认 20,最大 100
参数示例:20
示例代码:size = 20
size = ,
参数含义:排序
数据类型:string
取值范围:仅支持业务字段名,如 "i1 desc"、"dt1 asc"
是否必选:否
注意事项:不传则不排序
参数示例:"i1 desc"
示例代码:sort = "i1 desc"
sort = ,
参数含义:排序方向
数据类型:bool
取值范围:true(降序)/ false(升序)
是否必选:否
注意事项:默认使用 true 降序
参数示例:true
示例代码:desc = true
desc = ,
参数含义:仅查当前设备数据
数据类型:bool
取值范围:true(仅当前设备)/ false(所有数据)
是否必选:否
注意事项:默认 false
参数示例:true
示例代码:is_me = true
is_me = ,
参数含义:条件过滤,多个条件为 AND 关系
数据类型:JSON(table)
是否必选:否
注意事项:aks、acs、avs 三个数组一一对应,缺一不可
参数示例:{aks = {"d1","d1"}, acs = {"ge","le"}, avs = {"2026-05-06 00:00:00","2026-05-06 23:59:59"}}
filter = ,
取值范围:包含 aks、acs、avs 子参数,如下:
{
参数含义:查询字段名数组
数据类型:string[]
取值范围:业务字段名 s1 s2 s3 s4 i1 i2 i3 i4 d1 d2 uni_key id,每项 1 个字段名
是否必选:是
注意事项:aks 长度决定条件数量,与 acs、avs 一一对应
参数示例:{"d1", "d1"}
示例代码:aks = {"d1", "d1"}
aks = ,
参数含义:操作符数组
数据类型:string[]
取值范围:eq gt ge lt le like nlike ne not in nin,每项 1 个操作符。eq(等于 =)、gt(大于 >)、ge(大于等于 >=)、lt(小于 <)、le(小于等于 <=)、like(模糊匹配 LIKE)、nlike(非模糊匹配 NOT LIKE)、ne/not(不等于 !=)、in(在集合中 IN)、nin(不在集合中 NOT IN)
是否必选:是
注意事项:与 aks、avs 数组一一对应,长度必须一致
参数示例:{"ge", "le"}
示例代码:acs = {"ge", "le"}
acs = ,
参数含义:条件值数组
数据类型:string[]
取值范围:每项为 1 个与 aks 字段类型匹配的字符串值。in/nin 时用逗号分隔多个值(如 "值1,值2")。日期时间格式如 "2026-05-06 00:00:00"
是否必选:是
注意事项:与 aks、acs 数组一一对应,长度必须一致;值类型需与查询字段匹配
参数示例:{"2026-05-06 00:00:00", "2026-05-06 23:59:59"}
示例代码:avs = {"2026-05-06 00:00:00", "2026-05-06 23:59:59"}
avs = ,
}
}
callback
参数含义:结果回调函数
数据类型:function
是否必选:否
注意事项:function(success, data) end。success 为 true 时 data.records 为记录数组,每条含 id、uni_key、s1-s4、i1-i4、d1-d2
示例代码:list_callback = function(success, data) log.info("total", data.total) end
返回值
操作结果通过 callback 函数异步回调:callback(success, result),success 为 true 表示成功,result 为服务端返回信息。
示例
-- 查询积分排行榜 Top 20
exapp.list_record({cls = 2, sort = "i1 desc", size = 20})
-- 带回调用法
exapp.list_record({cls = 2, sort = "i1 desc", size = 20},
function(success, data)
if success and data and data.records then
log.info("共" .. data.total .. "条记录")
for i, rec in ipairs(data.records) do
log.info("记录" .. i, "id=" .. rec.id, "i1=" .. rec.i1, "s1=" .. rec.s1)
end
else
log.warn("查询失败", data)
end
end)
-- 查询当日数据
exapp.list_record({
cls = 2,
filter = {
aks = {"d1", "d1"},
acs = {"ge", "le"},
avs = {"2026-05-06 00:00:00", "2026-05-06 23:59:59"}
}
})
4.1.4 exapp.delete_record(params[, callback])
功能
删除记录。通过 id 精确匹配。
参数
params
参数含义:删除参数表
数据类型:table
是否必选:是
注意事项:id 为必填,来自 list_record 返回的 records[i].id
参数示例:{cls = 2, id = "2053765709500825602"}
示例代码:params = {cls = 2, id = "2053765709500825602"}
取值范围:包含 cls、id 子参数,如下:
{
参数含义:业务分类标记
数据类型:int
取值范围:由开发者自定义的正整数
是否必选:是
注意事项:同 add 接口
参数示例:2
示例代码:cls = 2
cls = ,
参数含义:服务端记录 ID
数据类型:string
是否必选:是
取值范围:来自 list_record 返回的 records[i].id
注意事项:传入时精确匹配单条记录
参数示例:"2053765709500825602"
示例代码:id = "2053765709500825602"
id = ,
}
callback
参数含义:结果回调函数
数据类型:function
是否必选:否
注意事项:function(success, result) end,success 为 true 表示成功,result 为服务端返回信息
示例代码:del_callback = function(success, result) log.info("result", success, result) end
返回值
操作结果通过 callback 函数异步回调:callback(success, result),success 为 true 表示成功,result 为服务端返回信息。
示例
-- 通过 id 精确删除(id 来自 list_record 返回结果)
exapp.delete_record({cls = 2, id = "2053765709500825602"})
-- 带回调用法
exapp.delete_record({cls = 2, id = "2053765709500825602"},
function(success, result)
if success then
log.info("删除成功")
else
log.warn("删除失败", result)
end
end)
4.1.5 exapp.iot_get_account_info()
功能
获取当前 IOT 登录状态和账号信息。
参数
无
返回值
local info = exapp.iot_get_account_info()
info
含义说明:当前 IOT 账号信息
数据类型:table
取值范围:包含 account(账号)、nickname(昵称)、is_guest(是否游客)
注意事项:is_guest == true 表示游客模式,数据库操作可能受限
返回示例:{account = "13800000000", nickname = "张三", is_guest = false}
示例
local info = exapp.iot_get_account_info()
if info.is_guest then
log.warn("请先登录IOT账号")
return
end
log.info("当前用户", info.nickname)
4.2 出厂应用使用接口
出厂应用(如应用商店)通过 exapp = require("exapp") 加载后调用以下接口。
4.2.1 接口概览
| 接口名称 | 功能描述 |
| exapp.init() | 初始化:扫描已后装应用,启动 IOT 自动登录。 |
| exapp.get_app_list(params) | 获取应用列表(云端或本地)。 |
| exapp.get_current_list() | 获取当前缓存的应用列表。 |
| exapp.list_installed() | 获取已后装应用信息表。 |
| exapp.install_remote_app(aid, url, app_name, category, sort) | 安装云端应用(下载→解压→写入 meta.json)。 |
| exapp.uninstall_remote_app(aid, category, sort) | 卸载云端应用(删除目录)。 |
| exapp.update_remote_app(aid, url, app_name, category, sort) | 更新云端应用(先卸载旧版再安装新版)。 |
| exapp.iot_login(account, password) | IOT 账号登录,RSA 加密传输。 |
| exapp.iot_logout() | IOT 账号登出。 |
| exapp.iot_auto_login() | 自动登录(exapp.init 时自动调用)。 |
4.2.2 exapp.init()
功能
初始化扩展应用管理库。扫描 /app_store/ 和 /sd/app_store/ 目录下的已后装应用,填充本地应用信息表,并启动 IOT 自动登录。
参数
无
返回值
local ok = exapp.init()
ok
含义说明:初始化是否成功
数据类型:boolean
取值范围:true(成功)
注意事项:始终返回 true
返回示例:true
示例
exapp.init()
4.2.3 exapp.get_app_list(params)
功能
获取应用列表。支持从云端获取和从本地获取已后装应用列表。
参数
params
参数含义:请求参数表
数据类型:table
是否必选:是
注意事项:category 为 "已安装" 时不需要网络;云端请求通过 APP_STORE_LIST_UPDATED 消息返回结果
参数示例:{category = "全部", sort = "recommend", page = 1, size = 10}
取值范围:包含 category、sort、page、size、query 子参数,如下:
{
参数含义:分类
数据类型:string
取值范围:"全部" / "游戏" / "工具" / "学习" / "通信" / "工业" / "已安装"
是否必选:否
注意事项:默认 "全部"
category = ,
参数含义:排序方式
数据类型:string
取值范围:"recommend" / "serial_asc" / "upload_time_asc" / "upload_time_desc" / "update_time_desc" / "weekly_download_desc" / "total_download_desc"
是否必选:否
注意事项:默认 "recommend"
sort = ,
参数含义:页码
数据类型:int
取值范围:从 1 开始的正整数
是否必选:否
注意事项:默认 1
page = ,
参数含义:每页数量
数据类型:int
是否必选:否
注意事项:默认 10
size = ,
参数含义:搜索关键词
数据类型:string
是否必选:否
query = ,
}
返回值
local ok = exapp.get_app_list(params)
ok
含义说明:是否成功发起请求
数据类型:boolean
取值范围:true(成功发起), false(网络未就绪)
返回示例:true
示例
exapp.get_app_list({category = "全部", sort = "recommend", page = 1, size = 10})
4.2.4 exapp.get_current_list()
功能
获取当前缓存的应用列表和是否有更多应用的标志。
参数
无
返回值
local apps, has_more = exapp.get_current_list()
apps
含义说明:当前缓存的应用列表
数据类型:table(数组)
注意事项:需先调用 exapp.get_app_list 填充缓存
has_more
含义说明:是否还有更多应用
数据类型:boolean
返回示例:true
示例
local apps, has_more = exapp.get_current_list()
if apps then
for _, app in ipairs(apps) do
log.info(app.title)
end
end
4.2.5 exapp.list_installed()
功能
获取本地已后装应用信息表。
参数
无
返回值
local installed_info, count = exapp.list_installed()
installed_info
含义说明:已后装应用信息表,key 为应用文件夹名
数据类型:table
取值范围:{["app_name"] = {cn_name, path, version, category, description, install_time, appid}, ...}
count
含义说明:已后装应用数量
数据类型:number
示例
local ins, cnt = exapp.list_installed()
for aid, info in pairs(ins) do
log.info(aid, info.cn_name, info.version)
end
4.2.6 exapp.install_remote_app(aid, url, app_name, category, sort)
功能
从云端下载并后装应用。流程:下载 ZIP → 解压到 /app_store/ → 写入 appid/install_time 等字段到 meta.json。
参数
aid
参数含义:应用 ID(文件夹名)
数据类型:string
是否必选:是
url
参数含义:应用下载地址
数据类型:string
是否必选:是
app_name
参数含义:应用名称
数据类型:string
是否必选:是
category
参数含义:分类
数据类型:string
是否必选:是
sort
参数含义:排序方式
数据类型:string
是否必选:是
返回值
无。操作结果通过 callback 函数异步回调:callback(success, result),success 为 true 表示成功,result 为服务端返回信息。
示例
sys.subscribe("APP_STORE_INSTALL", function(aid, url, app_name, category, sort)
exapp.install_remote_app(aid, url, app_name, category, sort)
end)
4.2.7 exapp.uninstall_remote_app(aid, category, sort)
功能
卸载应用,删除 /app_store/<aid>/ 目录。
参数
aid
参数含义:应用 ID
数据类型:string
是否必选:是
category
参数含义:分类
数据类型:string
是否必选:是
sort
参数含义:排序方式
数据类型:string
是否必选:是
返回值
无。操作结果通过 callback 函数异步回调:callback(success, result),success 为 true 表示成功,result 为服务端返回信息。
示例
sys.subscribe("APP_STORE_UPDATE", function(aid, url, app_name, category, sort)
exapp.update_remote_app(aid, url, app_name, category, sort)
end)
4.2.8 exapp.update_remote_app(aid, url, app_name, category, sort)
功能
更新应用:卸载旧版 → 下载新版 → 解压安装。参数同 install_remote_app。
返回值
无。操作结果通过 callback 函数异步回调:callback(success, result),success 为 true 表示成功,result 为服务端返回信息。
4.2.9 exapp.iot_login(account, password)
功能
IOT 账号登录。密码使用 RSA 公钥加密后 Base64 编码传输,凭据自动存入 fskv。
参数
account
参数含义:IOT 账号(手机号)
数据类型:string
是否必选:是
password
参数含义:IOT 密码
数据类型:string
是否必选:是
返回值
无。操作结果通过 callback 函数异步回调:callback(success, result),success 为 true 表示成功,result 为服务端返回信息。
示例
sys.subscribe("IOT_LOGIN_REQUEST", function(account, password)
exapp.iot_login(account, password)
end)
4.2.10 exapp.iot_logout()
功能
登出,清除 fskv 凭据,恢复游客模式。
参数
无
返回值
无。操作结果通过 callback 函数异步回调:callback(success, result),success 为 true 表示成功,result 为服务端返回信息。
示例
exapp.iot_logout()
4.2.11 exapp.iot_auto_login()
功能
自动登录。从 fskv 读取凭据尝试 RSA 加密登录,exapp.init() 时自动调用。
参数
无
返回值
无。操作结果通过 callback 函数异步回调:callback(success, result),success 为 true 表示成功,result 为服务端返回信息。
示例
-- exapp.init() 内部自动调用,一般无需手动调用
exapp.iot_auto_login()
五、产品支持说明
exapp 扩展应用管理库可以在支持 AirUI 的合宙 LuatOS 设备上使用。