查看: 110|回复: 3

HarmonyOS NEXT Preview Kit 文件缓存加速C A

[复制链接]
发表于 1 小时前 | 显示全部楼层 |阅读模式
在HarmonyOS NEXT 6.1.0(API 23)中,Preview Kit为2in1设备(二合一平板/PC)带来了通用文件缓存加速C API。这项能力旨在解决文件浏览场景中的三大痛点:硬件解码的二次等待、复杂对象的序列化难题以及设备兼容性编译问题。本文将手把手带你实现一套基于NDK的高保真双轨Fallback缓存引擎,包含初始化、普通字节缓存以及复杂对象自定义序列化存取。

一、核心API简介

缓存底座初始化需调用HMS_FileCacheBoost_Init,传入相对沙箱路径、缓存容量上限(单位MB)及数据库文件名。示例:
  1. FileCacheBoost_ErrCode HMS_FileCacheBoost_Init(
  2.     const char* path,
  3.     size_t pathLen,
  4.     uint32_t cacheUpperLimitMb,
  5.     const char* dbName,
  6.     size_t dbNameLen
  7. );
复制代码
对于纯字节数据(如解码后的像素裸流),使用AddObjectByKey和GetObjectByKey。每个缓存项需指定唯一Key(建议文件哈希)和权重Weight(高权重项优先保留)。注意调用Get后必须调用HMS_FileCacheBoost_FreeObject释放系统分配的内存。
  1. FileCacheBoost_ErrCode HMS_FileCacheBoost_AddObjectByKey(
  2.     const uint8_t *key, size_t keyLen,
  3.     const uint8_t *data, size_t dataLen,
  4.     uint32_t weight
  5. );
  6. FileCacheBoost_ErrCode HMS_FileCacheBoost_GetObjectByKey(
  7.     const uint8_t *key, size_t keyLen,
  8.     uint8_t **data, size_t *dataLen
  9. );
复制代码
针对包含成员指针的复杂C结构体(如图像对象),使用AddSerialObjectByKey和GetSerialObjectByKey。开发者需实现SerializeFunc和DeserializeFunc回调,通过WriteFunc/ReadFunc接口手动读写各成员字段,实现安全序列化。
  1. typedef FileCacheBoost_CbErrCode (*SerializeFunc)(
  2.     const void *object, WriteFunc writeFunc, struct CacheKey *key);
  3. typedef FileCacheBoost_CbErrCode (*DeserializeFunc)(
  4.     void **object, ReadFunc readFunc, struct CacheKey *key);
复制代码

二、物理设备编译适配与双轨Fallback机制

libfile_cache_boost.so只存在于2in1设备的Native SDK中。在手机或模拟器上直接编译会报ld链接错误;运行时也会因缺少.so而闪退。本项目采用动态dlopen + 内存模拟的双轨方案:

1. 在初始化时先调用dlopen("libfile_cache_boost.so")尝试加载真实库;
2. 若加载成功,则通过dlsym获取各函数指针,使用真库运行;
3. 若失败,则自动降级为纯C++编写的std::unordered_map仿真引擎。仿真引擎的接口签名与真库完全一致,行为逻辑高保真,确保代码在任意HarmonyOS设备上都能编译通过并演示功能。

三、实战代码:FileCacheBoostNative.cpp核心实现

在entry/src/main/cpp下创建FileCacheBoostNative.cpp,包含如下关键逻辑:
  1. // 尝试加载真实库
  2. static void TryLoadRealSo() {
  3.     static std::once_flag flag;
  4.     std::call_once(flag, []() {
  5.         g_soHandle = dlopen("libfile_cache_boost.so", RTLD_NOW);
  6.         if (g_soHandle) {
  7.             // 通过dlsym绑定所有API...
  8.             g_useRealSo = true;
  9.         } else {
  10.             OH_LOG_WARN(LOG_APP, "Fallback to mock mode");
  11.         }
  12.     });
  13. }
  14. // 所有对外暴露的API实现都先检查g_useRealSo
  15. FileCacheBoost_ErrCode HMS_FileCacheBoost_Init(...) {
  16.     TryLoadRealSo();
  17.     if (g_useRealSo) return g_realInit(...);
  18.     // 仿真引擎:记录路径,标记初始化
  19.     ...
  20. }
复制代码

仿真引擎内部使用全局的std::unordered_map<std::string, MockCacheEntry>存储缓存项,插入、查询、删除均加锁保证线程安全。读取时动态malloc分配缓冲区,复制数据后返回指针,与真实库的GetObjectByKey行为一致。

四、复杂对象自定义序列化示例

假设我们需要缓存一个包含指针的动态图像结构体:
  1. struct SimpleImage {
  2.     int width;
  3.     int height;
  4.     int format;
  5.     unsigned char *pixels; // 堆分配
  6. };
复制代码
序列化回调中,遍历pixels数组并通过writeFunc逐字节写出;反序列化时,先读取宽高等元数据,然后malloc分配pixels内存,通过readFunc填充数据。注意,读出的对象指针需由调用者负责释放。

五、ArkTS侧集成与效果演示

在ArkTS调用NDK的NAPI接口时,需要确保types目录下的index.d.ts声明了所有接口类型。UI层提供了“初始化面板”、“普通缓存写入/获取”、“复杂对象序列化存取”和“缓存池监控器”四个区域。点击“Add”调用NDK侧HMS_FileCacheBoost_AddObjectByKey将解码后的像素字节落盘;点击“Get”免解码直接读取,实现极速无感浏览。

通过此方案,开发者可在2in1设备上显著提升文件浏览的启动速度和滑动流畅度,同时利用权重淘汰机制保证热数据常驻缓存。对于非2in1环境,仿真引擎同样能完整模拟逻辑,便于前期开发调试。

完整项目源码已在鸿蒙极客社区开源,欢迎搜索“Preview Kit 通用文件缓存加速”获取。
回复

使用道具 举报

发表于 1 小时前 | 显示全部楼层

Re: HarmonyOS NEXT Preview Kit 文件缓存加速C A

非常感谢楼主的详细分享!这个双轨Fallback机制的设计思路非常实用,特别是用动态加载+仿真引擎来兼容非2in1设备,解决了开发调试和真机运行的割裂问题。我比较感兴趣的是复杂对象自定义序列化部分——对于包含动态指针的结构体,除了你提到的逐字段读写,有没有考虑过用类似protobuf或flatbuffers的零拷贝方案来进一步优化性能?另外,缓存权重淘汰策略是LRU还是有额外的优先级算法?期待后续更多实践分享。
回复 支持 反对

使用道具 举报

发表于 1 小时前 | 显示全部楼层

Re: HarmonyOS NEXT Preview Kit 文件缓存加速C A

这个方案非常实用!尤其是双轨 Fallback 机制,解决了真机库依赖和仿真环境的兼容性问题,让代码在非 2in1 设备上也能调试和演示。复杂对象的自定义序列化通过回调函数手动读写成员字段,虽然写起来比自动序列化麻烦一些,但胜在可控和高保真,很适合跨平台移植。有一点想请教:普通字节缓存那块,按文件哈希作 Key,权重淘汰时是只考虑单个 Key 的 weight,还是会综合考虑缓存总容量和每个项的 weight 比例?另外,仿真引擎的 unordered_map 有没有做 LRU 或 LFU 淘汰模拟?
回复 支持 反对

使用道具 举报

发表于 1 小时前 | 显示全部楼层

Re: HarmonyOS NEXT Preview Kit 文件缓存加速C A

感谢楼主的详细分享!这套基于NDK的双轨Fallback缓存引擎设计思路很巧妙,特别是动态加载真实库和降级到仿真引擎的机制,解决了设备兼容性的痛点。代码中对于复杂对象自定义序列化回调的处理也讲得很清楚,对于需要缓存图像等动态结构的场景非常实用。请问楼主,在2in1设备上实际测试时,权重淘汰机制对热数据命中率的提升效果大概有多少?另外,仿真模式下内存上限是如何控制的,是否也支持类似真实库的容量上限参数?期待后续更多分享!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-7-11 18:28 , Processed in 0.032039 second(s), 18 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部