如何销毁AIDL存根?

时间:2013-03-14 07:42:19

标签: android android-service aidl

我有这样的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实例的引用,以便在客户端调用方法时能够访问它们。

1 个答案:

答案 0 :(得分:0)

当你说Binder的东西保持对BarStub实例的引用以便能够随时访问它们时,你是对的。实际上,Binder对象是系统范围内的垃圾收集对象,因此当没有进程可以访问它们时它们就不再存在。

我建议两个选择:

  • 不要将destroySelf()视为实际销毁对象的东西,而是将其置于不活动的状态。然后,在所有其他方法调用(例如doStuff())中检查对象的状态,如果对象处于非活动状态则返回错误。
  • 更好的是,使用设计Android Binder而不是反对它。跨进程引用计数可能就是您想要的。具体来说,我会这样做:
    • 删除destroySelf()
    • 在服务范围内,请勿保留对Bar
    • 的引用
    • 如果服务确实知道Bar已被销毁,您可以在其上调用linkToDeath。但是,我不相信你可以保留它的参考,否则它永远不会被销毁。