
回复
大家好!我是小L,专注于鸿蒙进程间通信的开发。当远端服务进程突然终止时,若缺乏有效处理,应用可能面临内存泄漏、连接残留等问题。本文将介绍鸿蒙IPC Kit的DeathRecipient
机制,教你如何优雅处理进程消亡后的资源回收。
鸿蒙DeathRecipient
机制:
// 1. 创建回调函数(处理资源回收)
void OnRemoteDied(void* userData) {
MyService* service = (MyService*)userData;
pthread_mutex_lock(&service->lock);
if (service->proxy) {
OHIPCRemoteProxy_Destroy(service->proxy); // 销毁代理
service->proxy = NULL;
}
pthread_mutex_unlock(&service->lock);
}
// 2. 绑定到远端代理
OHIPCDeathRecipient* recipient = OH_IPCDeathRecipient_Create(
OnRemoteDied, myService, NULL // 回调函数、用户数据、释放回调
);
OH_IPCRemoteProxy_AddDeathRecipient(proxy, recipient); // 注册通知
// 3. 注销(不再需要时)
OH_IPCRemoteProxy_RemoveDeathRecipient(proxy, recipient);
OH_IPCDeathRecipient_Destroy(recipient);
void OnRemoteDied(void* userData) {
MyService* service = (MyService*)userData;
pthread_mutex_lock(&service->lock);
if (service->isDead) return; // 标记已处理,避免重复执行
service->isDead = true;
// 执行资源回收...
pthread_mutex_unlock(&service->lock);
}
资源类型 | 回收方法 | 优先级 |
---|---|---|
远端代理对象 | OHIPCRemoteProxy_Destroy() | ★★★★★ |
跨进程句柄 | OH_IPCObject_Release() | ★★★★☆ |
共享内存 | shm_unlink() + munmap() | ★★★☆☆ |
void OnRemoteDied(void* userData) {
MyService* service = (MyService*)userData;
pthread_t timerId;
pthread_create(&timerId, NULL, ReconnectService, service); // 启动重连线程
}
void* ReconnectService(void* arg) {
MyService* service = (MyService*)arg;
sleep(5); // 等待避免频繁重连
service->proxy = GetServiceProxy("com.example.RemoteService");
if (service->proxy) {
RegisterDeathRecipient(service->proxy, OnRemoteDied, service); // 重新注册通知
}
return NULL;
}
typedef struct {
OHIPCRemoteProxy* proxy;
pthread_mutex_t lock;
bool isConnected;
} DoorLockService;
void OnLockDied(void* userData) {
DoorLockService* service = (DoorLockService*)userData;
pthread_mutex_lock(&service->lock);
if (service->isConnected) {
service->isConnected = false;
OHIPCRemoteProxy_Destroy(service->proxy); // 销毁代理
ShowToast("门锁已离线"); // 通知用户
StartReconnectTimer(service); // 启动重连定时器
}
pthread_mutex_unlock(&service->lock);
}
指标 | 未处理 | 处理后 |
---|---|---|
内存泄漏 | 20KB/次断连 | 0KB |
僵尸连接 | 5个/小时 | 0个 |
用户投诉 | 12次/周 | 1次/周 |
错误:在回调中执行耗时操作(如文件写入、网络请求)。
正确:仅做轻量级清理,耗时任务移交子线程。
错误:先注销通知再销毁代理,可能丢失通知。
OH_IPCRemoteProxy_RemoveDeathRecipient(proxy, recipient); // ❌ 先注销
OHIPCRemoteProxy_Destroy(proxy);
正确:直接销毁代理,系统自动处理通知注销。
OHIPCRemoteProxy_Destroy(proxy); // ✅ 自动移除通知