awtk/docs/how_to_set_custom_load_asset.md
2024-04-27 08:50:12 +08:00

108 lines
4.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 如何自定义资源加载方式?
## 1 介绍
如果 AWTK 默认的资源加载方式无法满足需求,例如在无文件系统的嵌入式平台上使用外扩 flash 用来存储资源,可以自定义资源的加载方式,只需调用 assets_manager_set_custom_load_asset() 并注册资源加载回调函数即可AWTK 加载资源时会优先调用用户自定义的加载方式,接口声明如下:
```c
typedef asset_info_t* (*assets_manager_load_asset_t)(void* ctx, /* 回调函数上下文 */
asset_type_t type, /* 资源的类型 */
uint16_t subtype, /* 资源的子类型 */
const char* name); /* 资源的名称 */
/**
* @method assets_manager_set_custom_load_asset
* 设置一个函数,该函数用于实现自定义加载资源。
*
* > 如果不支持文件系统开发者可以设置一个加载资源的回调函数从flash或其它地方读取资源。
*
* @param {assets_manager_t*} am asset manager对象。
* @param {assets_manager_load_asset_t} custom_load_asset 回调函数。
* @param {void*} ctx 回调函数的上下文。
*
* @return {ret_t} 返回RET_OK表示成功否则表示失败。
*/
ret_t assets_manager_set_custom_load_asset(assets_manager_t* am,
assets_manager_load_asset_t custom_load_asset,
void* ctx);
```
## 2 示例
此处以 STM32F429 平台为例,上面外扩了一块 32MB 的 SPI Flash在本例子中会使用平台封装好的 W25QXX 库函数对这块 Flash 进行读写。
### 2.1 打包资源
在使用 AWTK Designer 进行界面设计时,修改"项目设置"里"资源打包方式"为"文件+常量"打包完成后可以在res/assets/default/inc 中看到打包完成的常量文件,文件一般为 .res 或者 .data 后缀,.res 后缀的文件一般为未解码的图片或者字体资源。
### 2.2 写入资源
在运行 AWTK 程序之前,需要先将数据写入外扩 Flash示例代码如下
```c
/*
* 此处以 home_page 界面的 UI 文件为例将数据写入Flash。
* 写入协议前256个字节为名称中间4个字节为资源大小最后为资源数组。
*/
#include "res/assets/default/inc/ui/home_page.data"
char *ui_name = "home_page";
u32 ui_size = sizeof(ui_home_page) /* 此处的ui_home_page为home_page.data文件中的资源数组*/
W25QXX_Write((u8*)ui_name,0,sizeof(ui_name)); /* 写入资源名称作为资源的唯一标识符 */
W25QXX_Write((u8*)(&ui_size),0 + 256,sizeof(u32)); /* 写入资源大小用来计算下一资源的偏移量*/
W25QXX_Write((u8*)ui_home_page,0 + 260,ui_size); /* 写入资源数组 */
```
### 2.3 注册自定义资源加载函数
接下来实现自定义资源加载函数,该函数需要在用户的 AWTK 应用程序中实现,示例代码如下:
```c
#define NAME_MAX_LEN 256
#define U32_SIZE 4
/* 自定义资源加载函数 */
asset_info_t* load_assets_from_flash(void* ctx, asset_type_t type,
uint16_t subtype, const char* name) {
u32 assets_size;
u32 start_position;
u8 assets_size_char[U32_SIZE];
u8 assets_name[NAME_MAX_LEN];
asset_info_t* info = NULL;
start_position = 0;
/* 该Flash中未写入数据的地方读取后的值为0xFF以此判断是否已经读取完毕 */
while (*assets_name != 0xFF) {
/* 读取资源名称 */
W25QXX_Read(assets_name, start_position, NAME_MAX_LEN);
/* 读取资源大小 */
W25QXX_Read(assets_size_char, start_position + NAME_MAX_LEN, U32_SIZE);
/* 将资源大小从数组转换为uint32类型 */
assets_size = assets_size_char[3] << 24 | assets_size_char[2] << 16 |
assets_size_char[1] << 8 | assets_size_char[0];
if (tk_str_eq(assets_name, name)) {
info = (asset_info_t*)malloc(assets_size);
memset(info, 0, assets_size);
/* 读取资源数组该数组的类型就为asset_info_t类型 */
W25QXX_Read((u8*)info, start_position + NAME_MAX_LEN + U32_SIZE, assets_size);
return info;
} else {
start_position = start_position + NAME_MAX_LEN + U32_SIZE + assets_size;
}
}
return info;
}
```
最后在项目application.c代码文件的application_on_launch()中注册该自定义资源加载函数,示例代码如下:
```c
static ret_t application_on_launch(void) {
assets_manager_set_custom_load_asset(assets_manager(), load_assets_from_flash, NULL);
return RET_OK;
}
```