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 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);    }

 

更多相关文章

  1. android 设置静态wifi地址
  2. Android中图形参数及图形内存信息获取
  3. Android读取设备内存大小
  4. Memory Analyzer(MAT)打开android eclipse Dump内存文件出现 Unkno
  5. Android 获得sdcard大小与内存大小工具类
  6. Android图片压缩及内存缓存
  7. 「抄底 Android 内存优化 3」 —— JVM 内存管理
  8. android 绘制折线图(AChartEngine)Linechart静态的
  9. android中 代码实现截图功能(静态+动态视频)

随机推荐

  1. 专项测试(三)内存泄漏调试经验分享 (一)
  2. Android(安卓)在线视频播放器(Vitamio)
  3. Android(安卓)targetSdkVersion了解一下
  4. android小白感悟:Android(安卓)Studio安装
  5. 详解Android中AsyncTask的使用
  6. Android读写XML(中)——SAX
  7. Android的ADB工具使用
  8. Android的内存泄露测试 mat
  9. Android位图操作
  10. [笨木头Cocos2dx045]让输入框在Android上