1

我有一个带有 AIDL 接口的服务,如下所示:

interface Bar {

    void doStuff();
    // ...
    void destroySelf();
}

interface Foo {

    // ...
    Bar createBar();
}

在服务实现中,Foo存根维护一个已创建Bar存根的列表,并且在Bar存根中,当destroySelf()被调用时,此实例将从列表中删除。

Bar我希望客户不再调用被破坏的实例,我该怎么做?

此客户端代码不会引发任何异常:

Bar bar = foo.createBar();
bar.destroySelf();
bar.doStuff();  //I want that to go "boom"

我查看了Binder实现,并且有一个destroy()从该方法调用的本机finalize()方法,但只有在垃圾收集器决定唤醒时才会调用它。我什至不确定这些Binder东西是否不会保留对BarStub实例的引用,以便在客户端调用一个方法时能够访问它们。

4

1 回答 1

0

当您说 Binder 东西保留对BarStub实例的引用以便能够随时访问它们时,您是对的。实际上,Binder 对象是在系统范围内进行垃圾收集的,因此它们仅在没有进程可以访问它们时才停止存在。

我建议两种选择:

  • 不要认为destroySelf()它实际上会破坏对象,而是将其置于非活动状态。然后,在所有其他方法调用中(例如doStuff())检查对象的状态并在对象处于非活动状态时返回错误。
  • 更好的是,使用Android Binder 的设计而不是反对它。跨进程引用计数可能正是您想要的。具体来说,我会这样做:
    • 消除destroySelf()
    • 在服务中,不要保留对Bar.
    • 如果服务真的知道Bar已被销毁,您可以调用linkToDeath它。但是,我不相信你可以保留对它的引用,否则它永远不会被破坏。
于 2013-03-15T08:36:14.433 回答