fix(share): 释放PixelMap/ImageSource + 指引监听 onDestroy 退订(code review C1/C2)

- C1: writeClipboardImage 在 finally 显式 pm.release()/source.release(),消除原生堆对象泄漏
- C2: 新增 guideCancelFn 字段;guide() 先退订悬挂监听再登记新监听、触发后清空;onDestroy() 退订;防用户不操作指引窗时 EventBus.once 永久悬挂
- I3: open 分支补注释说明乐观回传有意不等 openLink 完成

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
lanterngamescn
2026-06-27 14:10:56 +08:00
co-authored by Claude Sonnet 4.6
parent e93d0627d4
commit b51b9be167
@@ -41,6 +41,8 @@ export class ShareProvider implements CapabilityProvider {
/** 落盘 + resultEvent 命名计数器(实例自增,避免 Math.random 串扰)。 */
private seq: number = 0;
private photoUploadCancel: (() => void) | undefined = undefined;
/** 当前指引窗一次性监听的退订函数(用户不操作时由 onDestroy/下一次 guide 退订,防悬挂泄漏)。 */
private guideCancelFn: (() => void) | undefined = undefined;
constructor() {
ShareProvider.instanceCount += 1;
@@ -62,6 +64,10 @@ export class ShareProvider implements CapabilityProvider {
this.photoUploadCancel();
this.photoUploadCancel = undefined;
}
if (this.guideCancelFn !== undefined) {
this.guideCancelFn();
this.guideCancelFn = undefined;
}
}
// —— 入站 ——
@@ -195,9 +201,17 @@ export class ShareProvider implements CapabilityProvider {
}
private guide(bean: SharetypeBean, platform: string, kind: string, filePath: string): void {
// 退订上一个可能悬挂的指引监听(用户上次未操作就再次触发分享)。
if (this.guideCancelFn !== undefined) {
this.guideCancelFn();
this.guideCancelFn = undefined;
}
this.seq += 1;
const resultEvent: string = `share.guide.${this.instanceId}.${this.seq}`;
EventBus.once(resultEvent, (p) => this.onGuideAction(bean, platform, kind, filePath, p));
this.guideCancelFn = EventBus.once(resultEvent, (p) => {
this.guideCancelFn = undefined;
this.onGuideAction(bean, platform, kind, filePath, p);
});
const req: ShareGuideRequest = { platform, contentKind: kind, resultEvent };
EventBus.emit(ShareEvents.SHOW_GUIDE, req);
}
@@ -212,6 +226,7 @@ export class ShareProvider implements CapabilityProvider {
const reportType: number = bean.sharefriend === '1' ? 1 : 2;
if (action === 'open') {
this.openApp(uiCtx, platform);
// 乐观回传:不等 openLink 完成即视为已发起(契约 sharesuccess 仅微信完整)。
if (platform === 'wechat') {
this.reportResult(2, reportType);
}
@@ -285,9 +300,13 @@ export class ShareProvider implements CapabilityProvider {
.catch((e: BusinessError) => this.log.w(`clipboard image failed: ${e.code} ${e.message}`));
} catch (e) {
this.log.w(`clipboard image init failed: ${(e as Error).message}`);
} finally {
pm.release();
}
}).catch((e: BusinessError) => {
this.log.w(`createPixelMap failed: ${e.code} ${e.message}`);
}).finally(() => {
source.release();
});
}