HarmonyOS 7 ModularObjectExtensionAbility 越连实例越多?连接复用和断开生命周期怎么管

ModularObjectExtensionAbility 把应用能力开放给其他应用调用。接入后最容易忽略的一句话是:每次连接都会创建新的 Extension 实例。如果把一次业务方法调用等同于一次 Connect,实例数会随着点击次数增长。

模块化对象连接、Proxy、Stub 与实例生命周期

先确认 API 26 的能力边界

客户端按 bundleName、moduleName、abilityName 建立连接;服务端经过创建与连接回调返回 Stub,系统转换为客户端 Proxy。Disconnect 后会进入断开和销毁流程,旧 Proxy 不应继续被业务缓存。

  • Connect 是连接实例边界,不是普通方法调用。
  • 并发请求应合并同一个 connecting Promise。
  • Disconnect 后必须清空 Proxy 和等待中的连接状态。

案例一:按钮每点一次都 Connect,十次操作生成十个实例

把连接成本藏进每个仓库方法会导致实例膨胀。连接管理器应区分 idle、connecting、ready 和 disconnecting。

type State = 'idle' | 'connecting' | 'ready' | 'disconnecting'
class Connection<T> {
  private state: State = 'idle'
  private proxy?: T
  private pending?: Promise<T>
  constructor(private connect: () => Promise<T>) {}
  acquire(): Promise<T> {
    if (this.state === 'ready' && this.proxy) return Promise.resolve(this.proxy)
    if (this.state === 'connecting' && this.pending) return this.pending
    this.state = 'connecting'
    this.pending = this.connect().then(value => { this.proxy = value; this.state = 'ready'; return value })
    return this.pending
  }
}

三个并发 acquire 只会触发一次真正连接,后续请求等待同一个结果。

案例二:Disconnect 完成后页面还保存着旧 Proxy

业务层长期保存 Proxy 时,连接管理器即使进入 idle,页面仍可能继续调用旧对象。应把 Proxy 的作用域缩短到一次回调。

class RemoteService<T> {
  constructor(private connection: Connection<T>) {}
  async withProxy<R>(action: (proxy: T) => Promise<R>): Promise<R> {
    const proxy = await this.connection.acquire()
    return action(proxy)
  }
}
// 页面只传入本次动作,不持久化 Proxy

业务只能在回调期间使用 Proxy,断开后旧引用更难泄漏到页面状态。

现象与判断对照

现象优先检查处理原则
实例随点击增长是否每次方法都 Connect状态机复用连接
退出后实例仍在是否执行 Disconnect绑定页面或租约生命周期
断开后 IPC 错误是否缓存旧 Proxy限制 Proxy 作用域
多页面互相断开是否缺少持有者计数增加连接租约

为什么选择这个实现

连接是资源,应让它在架构中可见。状态机负责只连一次,租约负责决定谁有权断开,业务方法负责调用,两者不混在一个函数里。

可复用边界

连接状态机可复用到多个模块化对象,但具体 Proxy 类型和重连策略应由各能力适配器提供。

验证记录

已执行并发 acquire 合并、连接失败回到 idle、close 后清空引用、多个持有者最后一个离开才断开。

本文的策略代码已在宿主 JavaScript 环境执行断言,用来验证状态、排序、去重或边界计算。它不等同于 HarmonyOS 7 API 26 工程编译,也不等同于真机系统能力验证;涉及系统回调、设备能力、窗口形态或跨应用 IPC 的部分,仍应在对应 SDK 与设备上完成端到端验收。

上线前检查清单

  • 连接键包含 bundle/module/ability
  • 并发连接合并
  • 服务端创建与销毁日志配对
  • 断开后 Proxy 不再暴露
  • 多页面共享使用租约
  • API 26 跨应用 IPC 真机验证

官方资料

实例膨胀不是服务端神秘泄漏,往往是客户端把 Connect 当成了普通函数。先固定连接生命周期,再谈业务调用。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐