Android Handler 内存泄漏问题

1. 问题
先看以下代码:

第一种写法:

public class MainActivity extends AppCompatActivity {

...
...
...

private class MyHandler extends Handler {
@Override
public void handleMessage(@NonNull Message msg) {
if (msg.what == 10086) {
mTv.setText(String.valueOf(msg.arg1));
}
}
}

...
...
...

}
第二种写法:

public class MainActivity extends AppCompatActivity {

...
...
...

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
};

...
...
...

}
}
?

对于 Handler?这两种创建方式,Android Studio 虽然不会报错,但是会有提醒:

意思是 Handler 类必须为静态,否则会造成泄漏。

2.原因
非静态内部类和匿名内部类会持有外部类的引用。在 Handler 消息队列还有正在处理或者未处理消息时候,消息队列中的 Message 持有 Handler 实例的引用。由于Handler 为非静态内部类或者匿名内部类时候,又持有外部类的引用,也就是持有外部 MainActivity 实例。而这样的引用关系会一直保持。

此时,如果销毁外部类(MainActivity 实例),由于存在引用关系,垃圾回收机制中,外部类(MainActivity 实例)就无法被回收,从而造成内存泄漏。

内存泄漏在 Android 开发是一个严重的问题,系统给每个应用分配的内存是固定的,一旦发生了内存泄漏,就会导致应用的可用内存越来越小,最终导致 OOM 的发生。

3.解决方法
方法1:静态内部类+弱引用

将 Handler 的子类设置成静态内部类,静态内部类不再默认持有外部类的引用,从而使得引用关系不再存在。同时,再加上使用弱引用(WeakReference)持有Activity实例,当发生GC时候,一旦发现了只具有弱引用的对象,不管当前内存是否足够,都会回收它的内存。

public class MainActivity extends AppCompatActivity {

...
...
...

private static class MyHandler extends Handler {
WeakReference<Activity> reference;

public MyHandler(Activity activity) {
reference = new WeakReference<>(activity);
}

@Override
public void handleMessage(@NonNull Message msg) {
if(null!=reference)
{
MainActivity activity = (MainActivity) reference.get();
if(null!=activity) {
if (msg.what == 10086) {
activity.mTv.setText(String.valueOf(msg.arg1));
}
}
}
}
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mHandler=new MyHandler(this);
...
...
...

}
}
?2. 及时清除消息

当外部类(Activity)生命周期结束时候,清除 Handler 消息队列里的所有消息。

@Override
protected void onDestroy() {
super.onDestroy();
mHandler.removeCallbacksAndMessages(null);

原文地址:https://www.cnblogs.com/ly570/p/11498554.html

时间: 2024-11-09 00:49:33

Android Handler 内存泄漏问题的相关文章

Android防止内存泄漏以及MAT的使用

Android发生内存泄漏最普遍的一种情况就是长期保持对Context,特别是Activity的引用,使得Activity无法被销毁.这也就意味着Activity中所有的成员变量也没办法销毁.本文仅介绍如何避免这种情况的发生,其他如Bitmap没有及时回收导致的OOM异常暂不讨论. 一.防止内存泄漏 什么情况下会长时间保持对某个Activity的引用呢?主要有以下两种情况: 1.某个static变量保持对Activity的引用 2.线程保持Activity的引用 由于静态变量是长驻内存的,甚至在

Android Handler内存泄露

前言 在Android开发中,使用Handler的地方很多,大致通常写法如下: private Handler handler = new Handler() { public void handleMessage(android.os.Message msg) { if (msg.what == 1) { mAdapter.notifyDataSetChanged(); } }};这段代码看似没什么问题,但是里面却有一个警告,警告信息如下: This Handler class should

Android 常见内存泄漏的解决方式

在Android程序开发中.当一个对象已经不须要再使用了,本该被回收时.而另外一个正在使用的对象持有它的引用从而导致它不能被回收.这就导致本该被回收的对象不能被回收而停留在堆内存中,内存泄漏就产生了. 内存泄漏有什么影响呢? 它是造成应用程序OOM的主要原因之中的一个.由于Android系统为每一个应用程序分配的内存有限.当一个应用中产生的内存泄漏比較多时.就难免会导致应用所须要的内存超过这个系统分配的内存限额,这就造成了内存溢出而导致应用Crash. 一.单例造成的内存泄漏 Android的单

RxJava在Android中内存泄漏解决以及RxJava的封装

本文转自:http://blog.csdn.net/adzcsx2 RxJava在现在是一个非常前卫的异步框架,也是由于他非常新,所以比较难以驾驭. 像okhttp直接在onStop或者onDestroy 调用它的cancel方法就行了,但是Rxjava并没有那么简单. 因为假如每次请求都得到Observable对象,然后再onStop中unsubscribe取消,这样很不利于封装.而且会造成代码量很多,所以我找到了用rxlifecycle的解决方案. 先导包 compile 'com.trel

Android Native内存泄漏检测方法

Android 检测 C/C++内存泄漏的方法越来越简便了,下面列举一下不同场景下检测C/C++内存泄漏的方法. Android O(针对root设备,调试APP) 1. 准备一个userdebug或eng版本手机,下载native_heapdump_viewer.py脚本备用 2. 执行以下命令 adb shell setprop wrap.<APP_PACKAGE_NAME> '"LIBC_DEBUG_MALLOC_OPTIONS=backtrace"' 3. 执行重现

RxJava在Android中内存泄漏解决以及RxJava的封装。

RxJava在现在是一个非常前卫的异步框架,也是由于他非常新,所以比较难以驾驭. 像okhttp直接在onStop或者onDestroy 调用它的cancel方法就行了,但是Rxjava并没有那么简单. 因为假如每次请求都得到Observable对象,然后再onStop中unsubscribe取消,这样很不利于封装.而且会造成代码量很多,所以我找到了用rxlifecycle的解决方案. 先导包 compile 'com.trello:rxlifecycle:0.5.0' compile 'com

利用 LeakCanary 来检查 Android 内存泄漏

前言 你被概率性的 OOM 困扰么?有时候,OOM 像幽灵一样,挥之不去,可真想把它揪出来时,又捉之不着.或许,是时候用 LeakCanary 来诊断一下了.它是一个用来检查 Android 下内存泄漏的开源库,这篇文章主要介绍其用法.架构和其背后的实现原理. Square 有篇文章介绍了开发这个库的原因.他们的一个付款流程里,需要用到用户的签名,他们直接用 Bitmap 来画签名,Bitmap 大小和屏幕分辨率是一样的.问题来了,在试图创建这个 Bitmap 对象时,概率性 OOM 如幽灵般相

Android内存泄漏

韩梦飞沙  韩亚飞  [email protected]  yue31313  han_meng_fei_sha #Android 内存泄漏总结 内存管理的目的就是让我们在开发中怎么有效的避免我们的应用出现内存泄漏的问题.内存泄漏大家都不陌生了,简单粗俗的讲,就是该被释放的对象没有释放,一直被某个或某些实例所持有却不再被使用导致 GC 不能回收.最近自己阅读了大量相关的文档资料,打算做个 总结 沉淀下来跟大家一起分享和学习,也给自己一个警示,以后 coding 时怎么避免这些情况,提高应用的体验

Android应用程序内存泄漏介绍

Android应用程序内存泄漏介绍 内存泄漏和内存溢出的区别 内存溢出(out of memory)是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory.比如在我们每个Android程序在运行时系统都会给程序分配一个一定的内存空间,当程序在运行中需要的内存超出这个限制就会报内存溢出(out of memory). 内存泄漏(memory leak)是指程序在申请内存后,无法释放已申请的内存空间.多次内存无法被释放,程序占用的内存会一直增加,直到超过系统的内存限制报内存