#鸿蒙通关秘籍#如何在TaskPool子线程中预加载.so库并通过句柄调用函数?

HarmonyOS
6天前
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
网络小魔头

在鸿蒙开发中,有时需要在子线程中预加载.so库并调用其中的函数。以下是详细步骤:

  1. 准备和配置.so文件

    • 将需要加载的.so文件放入工程目录中,并在CMakeLists中使用target_link_directories命令添加预加载库的链接目录。
    target_link_directories(preloadso PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/${OHOS_ARCH}/)
    
  2. 链接.so文件

    • 使用target_link_libraries命令,将需要预加载的.so库链接到项目。
    target_link_libraries(preloadso PUBLIC libhilog_ndk.z.so libace_napi.z.so global_handlers libnativerawfile.so)
    
  3. 加载.so文件

    • 定义一个全局对象global_handlers存放加载的句柄。在Native层的Preload接口中,使用dlopen函数加载库,并将句柄保存到global_handlers
    std::unordered_map<std::string, void *> global_handlers;
    
    // 在 Preload 接口中
    void *handler = dlopen(path, RTLD_LAZY);
    if (handler != nullptr) {
        global_handlers[std::string(path)] = handler;
    }
    
  4. 调用加载接口

    • ArkTS层使用TaskPool创建子线程,通过preload接口调用Native层的Preload接口,加载.so库。
    @Concurrent
    function preloadSO(): string[] {
        return napi.preload(Constants.LIBRARY_PATH_ARRAY);
    }
    
    export function preloadSOByTaskPool(): void {
        let task: taskpool.Task = new taskpool.Task(preloadSO);
        try {
            taskpool.execute(task, taskpool.Priority.HIGH).then((res: string[]) => {
                logger.info(TAG, '%{public}s', 'PreloadSOByTaskPool:' + JSON.stringify(res));
            })
        } catch (err) {
            logger.error(TAG, "PreloadSOByTaskPool: execute failed, " + (err as BusinessError).toString());
        }
    }
    
  5. 在Ability的onCreate生命周期中调用预加载函数

    onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
         preloadSOByTaskPool();
    }
    

通过上述步骤,可以在鸿蒙系统中实现子线程中预加载.so库并调用其中的函数。

分享
微博
QQ
微信
回复
6天前
相关问题
如何在Native层加载so
1111浏览 • 1回复 待解决