2013-03-14 68 views
1

我有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實施且存在從finalize()方法稱爲destroy()本地方法,但只有當所謂的垃圾收集器決定喚醒。我甚至不確定Binder的東西沒有保留對BarStub實例的引用,以便在客戶端調用方法時能夠訪問它們。

回答

0

你說得對,當你說粘結劑的東西保持參考BarStub實例能夠訪問他們每當。實際上,Binder對象是系統範圍內的垃圾收集對象,因此它們只有在沒有進程訪問它們時纔會停止存在。

我建議兩個選項:

  • 不要以爲destroySelf()的東西,實際上破壞了對象,而是把它放到它是不活動的狀態。然後,在所有其他方法調用(例如doStuff())中檢查對象的狀態,並在對象處於非活動狀態時返回錯誤。
  • 更好的是,工作 Android Binder的設計,而不是反對它。跨進程引用計數可能正是你想要的。具體而言,我應該這樣做:
    • 刪除destroySelf()
    • 在服務,不保持到Bar參考。
    • 如果服務確實知道Bar已被銷燬,您可以撥打linkToDeath。但是,我不相信你可以保留對它的引用,否則它永遠不會被銷燬。
+0

選項2是不可行的。在服務方面,業務邏輯迫使我知道從'FooStub'實例實例化的'BarStub'列表。所以'destroySelf'是必要的。 – 2013-03-15 10:29:42