【Android】Handler 内存泄漏原因

本文讲解 Handler 内存泄漏原因,以及为什么其他的内部类没有说过有这个问题。

答:因为它会持有 Activity 。

解:跟匿名内部类有关,举个匿名内部类写法的例子:

定义一个 Handler ,然后 new 一个 Handler 。

Handler handler = new Handler() {

    @Override public void handleMessage(@NonNull Message msg) {
        super.handleMessage(msg);
    }
};

一个内部类会有一个特征:默认会持有外部类的对象。

Handler 处理原理:

发送消息(handler.send)和处理消息(handler.dispatch)是同一个 Handler 。

Q:为什么在子线程里通过 Handler 发送的消息,在主线程里还能用同一个 Handler ?

A:查看 Handler 源码

Handler 调用 sendMessageAtTime

public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
    ...
    return enqueueMessage(queue, msg, uptimeMillis);
}

sendMessageAtTime 调用 

private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
    msg.target = this;
    ...
}

会把这个 this (也就是 Handler) 赋值给 Message 的 target。

也就是说 MessageQueue 会持有 Message ,Message 会包含一个 target(Handler),这个 target 就会持有 Activity 。

Message 会放到队列里,在队列里 delay 一定时间,意味着 Message 一直存在于队列里面。也就意味着 MessageQueue 要在 delay 时间后处理这个 Message ,Message 会在 delay 时间后解除和 Handler 的关系,也就意味着 delay 时间后解除和 Activity 的关系。如果 Message 没有得到及时的处理,意味着 Activity 会一直被 Message 持有,而 Message 就会一直放在 MessgaeQueue 里面。MessageQueue 属于内存。

所以内存该释放的时候没释放,就会导致内存泄漏。

Q:如何解决这个问题?

A:1⃣️Handler 使用静态变量 2⃣️弱引用

如果本文对你有帮助,请点赞支持!!!

猜你喜欢

转载自blog.csdn.net/cnwutianhao/article/details/107646483
今日推荐