2

假设如下:

public interface Listener {
   public void onListen();
}

public class ActionClass {

   WeakReference<Listener> listener = null;

   public void doAction(String action, Listener listener) {
      this.listener = new WeakReference<Listener>(listener);
      doTheAction(action);
   }

   public void actionComplete() {
     if (listener != null && listener.get() != null)
          listener.onListen();

   } 
}

public class AnotherClass {
   ActionClass actioner = new ActionClass();
   void init()  {
      actioner.doAction("something", new Listener() {
          onListened() {
              Log.d("Tag", "Action complete!");
          }
      };


   }
}

抱歉,如果有拼写错误/语法错误,这更多的是伪代码。

无论如何,很多时候,当“Action”完成时,对侦听器的 WeakReference 将被 GCed,即使“AnotherClass”的实例仍然存在。有没有办法避免这种情况?

4

2 回答 2

6

让 AnotherClass 实现 Listener 或在里面有一个私有实例。IE:

Listener myListener = new Listener() {
  public void onListed() {
    ....
  }
};

对侦听器的 AnotherClass 引用将使其引用保持活动状态(直到您的程序中有 AnotherClass 引用)

于 2013-09-29T14:23:53.260 回答
3

顺便说一句,不仅仅是作为答案,您的代码中有一个错误:

if (listener != null && listener.get() != null)
    listener.get().onListen();

此代码包含一个竞争条件,因为 GC 可以在您检查它null的时间和调用它的时间之间获取引用。你需要用这个替换它:

if(listener != null) {
    Listener l = listener.get():
    if(l != null)
        l.onListen();
}

这通过在局部变量中引用来使任何获得的侦听器保持活动状态。

此外,您应该知道 GC 也可能会Listener比您还活着的时间长得多AnotherClass,因为无法保证它何时会被收割,但我想您知道这一点。

于 2013-09-29T20:12:52.863 回答