一、混合开发架构与原理
1. 混合开发核心架构
HarmonyOS混合开发采用分层设计:
- ArkTS层:UI组件和业务逻辑,使用声明式开发范式
- Node-API桥接层:提供类型安全的跨语言通信机制
- Native层:C/C++高性能计算和系统级功能
- 渲染管线:统一管理UI渲染,支持硬件加速
2. 开发环境配置
在 module.json5
中配置Native模块依赖:
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.INTERNET",
"reason": "$string:internet_permission_reason",
"usedScene": {
"abilities": ["MainAbility"],
"when": "always"
}
}
],
"nativeLibrary": "libnative_module.so",
"abilities": [
{
"name": "MainAbility",
"srcEntry": "./ets/MainAbility/MainAbility.ets",
"nativeLibraryPath": "libs/arm64-v8a"
}
]
}
}
二、Node-API基础开发
1. Native模块初始化
创建基础的Native模块结构和初始化代码:
// native_module.h
#ifndef NATIVE_MODULE_H
#define NATIVE_MODULE_H
#include "napi/native_api.h"
#include <string>
#include <vector>
// 模块初始化函数
napi_value Init(napi_env env, napi_value exports);
// 加法函数示例
napi_value Add(napi_env env, napi_callback_info info);
// 字符串处理函数
napi_value ProcessString(napi_env env, napi_callback_info info);
// 回调函数示例
napi_value RegisterCallback(napi_env env, napi_callback_info info);
#endif // NATIVE_MODULE_H
// native_module.cpp
#include "native_module.h"
#include <cmath>
#include <thread>
// 模块初始化
napi_value Init(napi_env env, napi_value exports) {
napi_property_descriptor desc[] = {
{"add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr},
{"processString", nullptr, ProcessString, nullptr, nullptr, nullptr, napi_default, nullptr},
{"registerCallback", nullptr, RegisterCallback, nullptr, nullptr, nullptr, napi_default, nullptr}
};
napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
return exports;
}
// 加法函数实现
napi_value Add(napi_env env, napi_callback_info info) {
size_t argc = 2;
napi_value args[2];
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
double value1, value2;
napi_get_value_double(env, args[0], &value1);
napi_get_value_double(env, args[1], &value2);
napi_value result;
napi_create_double(env, value1 + value2, &result);
return result;
}
2. 类型安全的数据转换
实现安全的类型检查和数据转换:
// 安全获取字符串参数
std::string GetStringFromNapi(napi_env env, napi_value value) {
size_t length;
napi_get_value_string_utf8(env, value, nullptr, 0, &length);
std::string result(length + 1, '\0');
napi_get_value_string_utf8(env, value, &result[0], result.size(), nullptr);
return result;
}
// 安全获取数组参数
std::vector<double> GetDoubleArrayFromNapi(napi_env env, napi_value value) {
std::vector<double> result;
uint32_t length;
napi_get_array_length(env, value, &length);
for (uint32_t i = 0; i < length; i++) {
napi_value element;
napi_get_element(env, value, i, &element);
double value;
napi_get_value_double(env, element, &value);
result.push_back(value);
}
return result;
}
// 类型检查函数
bool IsNumberArray(napi_env env, napi_value value) {
bool is_array;
napi_is_array(env, value, &is_array);
if (!is_array) return false;
uint32_t length;
napi_get_array_length(env, value, &length);
for (uint32_t i = 0; i < length; i++) {
napi_value element;
napi_get_element(env, value, i, &element);
napi_valuetype type;
napi_typeof(env, element, &type);
if (type != napi_number) return false;
}
return true;
}
三、高级数据类型处理
1. 对象和复杂数据结构
处理复杂的JavaScript对象:
// 从Napi对象中提取字段
napi_value ExtractObjectFields(napi_env env, napi_callback_info info) {
size_t argc = 1;
napi_value args[1];
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
// 获取对象属性
napi_value name_value, age_value, scores_value;
napi_get_named_property(env, args[0], "name", &name_value);
napi_get_named_property(env, args[0], "age", &age_value);
napi_get_named_property(env, args[0], "scores", &scores_value);
// 提取值
std::string name = GetStringFromNapi(env, name_value);
int age;
napi_get_value_int32(env, age_value, &age);
std::vector<double> scores = GetDoubleArrayFromNapi(env, scores_value);
// 计算平均分
double sum = 0;
for (double score : scores) sum += score;
double average = scores.empty() ? 0 : sum / scores.size();
// 创建结果对象
napi_value result;
napi_create_object(env, &result);
napi_value average_value;
napi_create_double(env, average, &average_value);
napi_set_named_property(env, result, "average", average_value);
napi_value summary_value;
std::string summary = name + " (age " + std::to_string(age) + ") average: " + std::to_string(average);
napi_create_string_utf8(env, summary.c_str(), summary.size(), &summary_value);
napi_set_named_property(env, result, "summary", summary_value);
return result;
}
2. 异步操作和线程安全
实现线程安全的异步操作:
// 异步工作结构体
struct AsyncWorkData {
napi_env env;
napi_deferred deferred;
napi_async_work work;
std::vector<double> data;
double result;
std::string error;
};
// 异步计算函数
void ExecuteAsyncWork(napi_env env, void* data) {
AsyncWorkData* work_data = static_cast<AsyncWorkData*>(data);
try {
// 模拟耗时计算
double sum = 0;
for (double value : work_data->data) {
sum += value;
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
work_data->result = sum / work_data->data.size();
} catch (const std::exception& e) {
work_data->error = e.what();
}
}
// 异步完成回调
void CompleteAsyncWork(napi_env env, napi_status status, void* data) {
AsyncWorkData* work_data = static_cast<AsyncWorkData*>(data);
if (status == napi_ok && work_data->error.empty()) {
napi_value result;
napi_create_double(env, work_data->result, &result);
napi_resolve_deferred(env, work_data->deferred, result);
} else {
napi_value error;
napi_create_string_utf8(env, work_data->error.c_str(), work_data->error.size(), &error);
napi_reject_deferred(env, work_data->deferred, error);
}
napi_delete_async_work(env, work_data->work);
delete work_data;
}
// 异步计算平均值
napi_value CalculateAverageAsync(napi_env env, napi_callback_info info) {
size_t argc = 1;
napi_value args[1];
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
// 创建Promise
napi_deferred deferred;
napi_value promise;
napi_create_promise(env, &deferred, &promise);
// 准备异步数据
AsyncWorkData* work_data = new AsyncWorkData();
work_data->env = env;
work_data->deferred = deferred;
work_data->data = GetDoubleArrayFromNapi(env, args[0]);
// 创建异步工作
napi_value resource_name;
napi_create_string_utf8(env, "CalculateAverage", NAPI_AUTO_LENGTH, &resource_name);
napi_create_async_work(env, nullptr, resource_name, ExecuteAsyncWork, CompleteAsyncWork, work_data, &work_data->work);
napi_queue_async_work(env, work_data->work);
return promise;
}
四、Native UI组件开发
1. 创建自定义Native组件
开发高性能的Native UI组件:
// native_ui_component.h
#ifndef NATIVE_UI_COMPONENT_H
#define NATIVE_UI_COMPONENT_H
#include "napi/native_api.h"
#include "arkui/native_node.h"
// 创建自定义Native组件
napi_value CreateNativeButton(napi_env env, napi_callback_info info);
// 设置组件属性
napi_value SetButtonProperties(napi_env env, napi_callback_info info);
// 注册组件事件
napi_value RegisterButtonEvent(napi_env env, napi_callback_info info);
#endif // NATIVE_UI_COMPONENT_H
// native_ui_component.cpp
#include "native_ui_component.h"
#include <map>
static std::map<std::string, ArkUI_NodeHandle> button_registry;
// 创建Native按钮组件
napi_value CreateNativeButton(napi_env env, napi_callback_info info) {
size_t argc = 1;
napi_value args[1];
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
// 获取按钮ID
std::string button_id = GetStringFromNapi(env, args[0]);
// 创建ArkUI节点
ArkUI_NodeHandle button_node = OH_ArkUI_CreateNode(ARKUI_NODE_BUTTON);
// 设置默认属性
ArkUI_NumberValue width_value[] = {{.f32 = 200}};
ArkUI_AttributeItem width_item = {.value = width_value, .size = 1};
OH_ArkUI_SetAttribute(button_node, ARKUI_NODE_WIDTH, &width_item);
ArkUI_NumberValue height_value[] = {{.f32 = 50}};
ArkUI_AttributeItem height_item = {.value = height_value, .size = 1};
OH_ArkUI_SetAttribute(button_node, ARKUI_NODE_HEIGHT, &height_item);
// 注册到映射表
button_registry[button_id] = button_node;
// 返回节点句柄
napi_value result;
napi_create_uint32(env, reinterpret_cast<uintptr_t>(button_node), &result);
return result;
}
2. 组件属性与事件处理
实现组件属性设置和事件回调:
// 设置按钮属性
napi_value SetButtonProperties(napi_env env, napi_callback_info info) {
size_t argc = 3;
napi_value args[3];
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
std::string button_id = GetStringFromNapi(env, args[0]);
std::string property_name = GetStringFromNapi(env, args[1]);
if (button_registry.find(button_id) == button_registry.end()) {
napi_throw_error(env, nullptr, "Button not found");
return nullptr;
}
ArkUI_NodeHandle button_node = button_registry[button_id];
if (property_name == "text") {
std::string text_value = GetStringFromNapi(env, args[2]);
ArkUI_AttributeItem text_item = {.string = text_value.c_str()};
OH_ArkUI_SetAttribute(button_node, ARKUI_NODE_BUTTON_LABEL, &text_item);
} else if (property_name == "color") {
std::string color_value = GetStringFromNapi(env, args[2]);
// 颜色转换逻辑...
}
return nullptr;
}
// 事件回调结构
struct ButtonEventData {
napi_env env;
napi_ref callback_ref;
std::string button_id;
};
// 按钮点击事件处理
void HandleButtonClick(ArkUI_NodeHandle node, ArkUI_NodeEventType event_type, void* data) {
ButtonEventData* event_data = static_cast<ButtonEventData*>(data);
napi_value callback;
napi_get_reference_value(event_data->env, event_data->callback_ref, &callback);
napi_value button_id;
napi_create_string_utf8(event_data->env, event_data->button_id.c_str(), event_data->button_id.size(), &button_id);
napi_call_function(event_data->env, nullptr, callback, 1, &button_id, nullptr);
}
// 注册按钮事件
napi_value RegisterButtonEvent(napi_env env, napi_callback_info info) {
size_t argc = 3;
napi_value args[3];
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
std::string button_id = GetStringFromNapi(env, args[0]);
std::string event_type = GetStringFromNapi(env, args[1]);
if (button_registry.find(button_id) == button_registry.end()) {
napi_throw_error(env, nullptr, "Button not found");
return nullptr;
}
// 创建事件数据
ButtonEventData* event_data = new ButtonEventData();
event_data->env = env;
event_data->button_id = button_id;
napi_create_reference(env, args[2], 1, &event_data->callback_ref);
// 注册事件监听器
if (event_type == "click") {
OH_ArkUI_RegisterNodeEvent(button_registry[button_id], ARKUI_NODE_ON_CLICK, HandleButtonClick, event_data);
}
return nullptr;
}
五、ArkTS与Native交互
1. ArkTS调用Native模块
在ArkTS中集成和调用Native功能:
// native_module.d.ts - 类型定义文件
declare namespace NativeModule {
function add(a: number, b: number): number;
function processString(input: string): string;
function calculateAverageAsync(data: number[]): Promise<number>;
function createNativeButton(buttonId: string): number;
function setButtonProperties(buttonId: string, property: string, value: any): void;
function registerButtonEvent(buttonId: string, eventType: string, callback: (buttonId: string) => void): void;
}
export default NativeModule;
// NativeIntegration.ets
import native from 'libnative.so';
import { BusinessError } from '@ohos.base';
@Component
struct NativeIntegrationExample {
@State calculationResult: number = 0;
@State processedText: string = '';
@State averageValue: number = 0;
@State buttonClickCount: number = 0;
// 同步Native调用
performCalculation(): void {
try {
this.calculationResult = native.add(15, 27);
} catch (error) {
console.error(`计算失败: ${(error as BusinessError).message}`);
}
}
// 异步Native调用
async calculateAverage(): Promise<void> {
try {
const data = [10, 20, 30, 40, 50];
this.averageValue = await native.calculateAverageAsync(data);
} catch (error) {
console.error(`异步计算失败: ${(error as BusinessError).message}`);
}
}
// 创建Native UI组件
setupNativeButton(): void {
try {
const buttonHandle = native.createNativeButton('main_button');
native.setButtonProperties('main_button', 'text', '点击我');
native.setButtonProperties('main_button', 'color', '#007DFF');
native.registerButtonEvent('main_button', 'click', (buttonId: string) => {
this.buttonClickCount++;
console.info(`按钮 ${buttonId} 被点击了 ${this.buttonClickCount} 次`);
});
} catch (error) {
console.error(`Native按钮创建失败: ${(error as BusinessError).message}`);
}
}
aboutToAppear() {
this.setupNativeButton();
}
build() {
Column() {
// 计算结果展示
Text(`同步计算结果: ${this.calculationResult}`)
.fontSize(18)
.margin({ bottom: 12 })
Text(`异步平均结果: ${this.averageValue.toFixed(2)}`)
.fontSize(18)
.margin({ bottom: 12 })
Text(`按钮点击次数: ${this.buttonClickCount}`)
.fontSize(18)
.margin({ bottom: 24 })
// 操作按钮
Button('执行同步计算')
.onClick(() => this.performCalculation())
.margin({ bottom: 12 })
Button('执行异步计算')
.onClick(() => this.calculateAverage())
.margin({ bottom: 12 })
// Native组件容器
Stack() {
// Native按钮将通过ContentSlot渲染在这里
ContentSlot()
.width(200)
.height(50)
}
.margin({ top: 20 })
}
.padding(24)
}
}
2. 性能优化与内存管理
实现高效的内存管理和资源清理:
// 资源清理函数
void CleanupNativeResources(napi_env env, napi_callback_info info) {
// 清理所有按钮资源
for (auto& pair : button_registry) {
OH_ArkUI_DestroyNode(pair.second);
}
button_registry.clear();
// 清理其他Native资源...
}
// 内存使用监控
napi_value GetMemoryUsage(napi_env env, napi_callback_info info) {
size_t rss = 0;
// 获取当前进程内存使用(实际项目中会使用系统API)
napi_value result;
napi_create_object(env, &result);
napi_value rss_value;
napi_create_int64(env, rss, &rss_value);
napi_set_named_property(env, result, "rss", rss_value);
return result;
}
// 对象生命周期管理
class ManagedObject {
public:
ManagedObject(napi_env env) : env_(env) {
napi_create_reference(env_, nullptr, 0, &wrapper_);
}
virtual ~ManagedObject() {
if (wrapper_ != nullptr) {
napi_delete_reference(env_, wrapper_);
}
}
void SetWrapper(napi_value wrapper) {
napi_create_reference(env_, wrapper, 1, &wrapper_);
}
private:
napi_env env_;
napi_ref wrapper_ = nullptr;
};
六、高级主题与最佳实践
1. 线程管理与同步
实现多线程环境下的安全操作:
// 线程安全队列
template<typename T>
class ThreadSafeQueue {
public:
void Push(T value) {
std::lock_guard<std::mutex> lock(mutex_);
queue_.push(std::move(value));
cond_.notify_one();
}
T Pop() {
std::unique_lock<std::mutex> lock(mutex_);
cond_.wait(lock, [this]{ return !queue_.empty(); });
T value = std::move(queue_.front());
queue_.pop();
return value;
}
private:
std::queue<T> queue_;
std::mutex mutex_;
std::condition_variable cond_;
};
// 工作线程管理
class WorkerThread {
public:
WorkerThread() : thread_(&WorkerThread::Run, this) {}
~WorkerThread() {
Stop();
if (thread_.joinable()) {
thread_.join();
}
}
void PostTask(std::function<void()> task) {
task_queue_.Push(std::move(task));
}
void Stop() {
PostTask([this]{ running_ = false; });
}
private:
void Run() {
while (running_) {
auto task = task_queue_.Pop();
task();
}
}
std::atomic<bool> running_{true};
ThreadSafeQueue<std::function<void()>> task_queue_;
std::thread thread_;
};
2. 错误处理与调试
实现完善的错误处理和调试机制:
// 错误处理工具
napi_value ThrowNativeError(napi_env env, const std::string& message, int error_code = 0) {
napi_value error_obj;
napi_create_object(env, &error_obj);
napi_value msg_value;
napi_create_string_utf8(env, message.c_str(), message.size(), &msg_value);
napi_set_named_property(env, error_obj, "message", msg_value);
napi_value code_value;
napi_create_int32(env, error_code, &code_value);
napi_set_named_property(env, error_obj, "code", code_value);
napi_throw(env, error_obj);
return nullptr;
}
// 调试日志
void LogDebugInfo(napi_env env, const std::string& message) {
napi_value console;
napi_get_global(env, "console", &console);
napi_value log_func;
napi_get_named_property(env, console, "log", &log_func);
napi_value msg_value;
napi_create_string_utf8(env, message.c_str(), message.size(), &msg_value);
napi_call_function(env, console, log_func, 1, &msg_value, nullptr);
}
// 性能监控
class PerformanceMonitor {
public:
void StartTimer(const std::string& name) {
timers_[name] = std::chrono::high_resolution_clock::now();
}
double StopTimer(const std::string& name) {
auto end = std::chrono::high_resolution_clock::now();
auto start = timers_[name];
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
return duration.count();
}
private:
std::map<std::string, std::chrono::time_point<std::chrono::high_resolution_clock>> timers_;
};
3. 模块注册与构建配置
完整的模块注册和构建配置:
// 模块注册
NAPI_MODULE_INIT() {
napi_value exports;
napi_create_object(env, &exports);
// 注册函数
napi_property_descriptor desc[] = {
{"add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr},
{"processString", nullptr, ProcessString, nullptr, nullptr, nullptr, napi_default, nullptr},
{"calculateAverageAsync", nullptr, CalculateAverageAsync, nullptr, nullptr, nullptr, napi_default, nullptr},
{"createNativeButton", nullptr, CreateNativeButton, nullptr, nullptr, nullptr, napi_default, nullptr},
{"setButtonProperties", nullptr, SetButtonProperties, nullptr, nullptr, nullptr, napi_default, nullptr},
{"registerButtonEvent", nullptr, RegisterButtonEvent, nullptr, nullptr, nullptr, napi_default, nullptr},
{"cleanupResources", nullptr, CleanupNativeResources, nullptr, nullptr, nullptr, napi_default, nullptr},
{"getMemoryUsage", nullptr, GetMemoryUsage, nullptr, nullptr, nullptr, napi_default, nullptr}
};
napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
return exports;
}
CMakeLists.txt 配置:
cmake_minimum_required(VERSION 3.4)
project(native_module)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 查找Node-API头文件
find_path(NAPI_INCLUDE_DIR napi/native_api.h)
find_library(NAPI_LIBRARY libnapi.so)
# 查找ArkUI Native头文件
find_path(ARKUI_INCLUDE_DIR arkui/native_node.h)
find_library(ARKUI_LIBRARY libarkui.so)
# 包含目录
include_directories(${NAPI_INCLUDE_DIR} ${ARKUI_INCLUDE_DIR})
# 创建共享库
add_library(native_module SHARED
native_module.cpp
native_ui_component.cpp
)
# 链接库
target_link_libraries(native_module ${NAPI_LIBRARY} ${ARKUI_LIBRARY})
通过掌握这些Native与ArkTS混合开发技术,你可以在HarmonyOS应用中实现高性能计算、复杂UI组件和系统级功能,充分发挥Native代码的性能优势,同时保持ArkTS的开发效率。
需要参加鸿蒙认证的请点击 鸿蒙认证链接