0

在我第一次从干净状态进入应用程序后,在处理程序内部,处理程序处理 MSG_PULLED 操作,但是对 main 的引用为空。弱引用不为空。这怎么可能发生?

受这篇文章的启发:这个 Handler 类应该是静态的,否则可能会发生泄漏:IncomingHandler

static class MainHandler extends Handler {
    private final WeakReference<MainActivity> wMain; 
    static int angle=0;
    public MainHandler(MainActivity main) {
        super();
        this.wMain = new WeakReference<MainActivity>(main);
    }

    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        MainActivity main = wMain.get();
        int what = msg.what;
        if(what == MSG_PULLED) {
            main.startAnim();
        } 
    }
}

以及我如何启动处理程序:

static MainHandler mainHandler;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mainHandler = new MainHandler(this);
        mainHandler.sendEmptyMessageDelayed(MSG_PULLED,500);
    }
4

1 回答 1

1

您的应用程序中的Activity实例会定期销毁并创建新实例,例如在旋转显示器时。

现在在这种情况下应该发生的是旧实例被垃圾收集并且只存在新实例。如果您将旧的保留在周围,则会造成泄漏。

由于Handler在没有更多消息(?)之前它们不能被垃圾收集(?),它们可以比Activity创建它们的 in 女巫活得更长,这通常会导致泄漏旧的Activity(直到Handler可以收集),因为Handler通常对他们的Activity.

您的代码中的方式通过仅保留与不阻止垃圾收集WeakReference的弱链接来解决该问题。Activity

问题是您get()以错误的方式使用该方法:get()只会在原始对象存在时返回它。当它消失时,你得到null。这里:Activity意志存在时它仍然是活跃的(由系统决定)。

null也不是一个大问题:当您nullActivity实例不再存在时(也许创建了一个新实例,也许它完全消失了),因此您无法再对它做任何有用的事情。即使您还有参考,动画也不会显示。

基本上像下面那样做,你的问题就解决了

@Override
public void handleMessage(Message msg) {
    super.handleMessage(msg);
    MainActivity main = wMain.get();

    // message arrived after activity death
    if (main == null) return;

    int what = msg.what;
    if(what == MSG_PULLED) {
        main.startAnim();
    } 
}

WeakReference自身 ( ) 不为空,wMain因为它本身作为成员变量被强烈引用。只是其中的内容可以/将null在某个时候出现。

于 2012-09-29T20:27:39.117 回答