跳转至

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"}
 取值范围:包含 clsuni_keys1-s4i1-i4d1-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) endsuccess  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 为记录数组,每条含 iduni_keys1-s4i1-i4d1-d2
 参数示例:{cls = 2, sort = "i1 desc", size = 20, is_me = true}
 示例代码:params = {cls = 2, sort = "i1 desc", size = 20, is_me = true}
 取值范围:包含 clsuni_keypagesizesortdescis_mefilter 子参数,如下:
    {
     参数含义:业务分类标记
     数据类型: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 关系
      数据类型:JSONtable
      是否必选:否
      注意事项:aksacsavs 三个数组一一对应,缺一不可
      参数示例:{aks = {"d1","d1"}, acs = {"ge","le"}, avs = {"2026-05-06 00:00:00","2026-05-06 23:59:59"}}
      filter = ,
      取值范围:包含 aksacsavs 子参数,如下:
      {
       参数含义:查询字段名数组
       数据类型:string[]
       取值范围:业务字段名 s1 s2 s3 s4 i1 i2 i3 i4 d1 d2 uni_key id,每项 1 个字段名
       是否必选:是
       注意事项:aks 长度决定条件数量,与 acsavs 一一对应
       参数示例:{"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
       是否必选:是
       注意事项:与 aksavs 数组一一对应,长度必须一致
       参数示例:{"ge", "le"}
       示例代码:acs = {"ge", "le"}
       acs = ,

       参数含义:条件值数组
       数据类型:string[]
       取值范围:每项为 1 个与 aks 字段类型匹配的字符串值。in/nin 时用逗号分隔多个值(如 "值1,值2")。日期时间格式如 "2026-05-06 00:00:00"
       是否必选:是
       注意事项:与 aksacs 数组一一对应,长度必须一致;值类型需与查询字段匹配
       参数示例:{"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) endsuccess  true  data.records 为记录数组,每条含 iduni_keys1-s4i1-i4d1-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"}
 取值范围:包含 clsid 子参数,如下:
    {
     参数含义:业务分类标记
     数据类型:int
     取值范围:由开发者自定义的正整数
     是否必选:是
     注意事项:同 add 接口
     参数示例:2
     示例代码:cls = 2
     cls = ,

     参数含义:服务端记录 ID
     数据类型:string
     是否必选:是
     取值范围:来自 list_record 返回的 records[i].id
     注意事项:传入时精确匹配单条记录
     参数示例:"2053765709500825602"
     示例代码:id = "2053765709500825602"
      id = ,
      }

callback

 参数含义:结果回调函数
 数据类型:function
 是否必选:否
 注意事项:function(success, result) endsuccess  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}
取值范围:包含 categorysortpagesizequery 子参数,如下:
    {
     参数含义:分类
     数据类型: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 设备上使用。