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 JNI java与C++传递String数组(引用类型)
  3. android 获取手机屏幕分辨率
  4. Android(安卓)Framewok引用第三方jar包
  5. Android项目:proguard混淆第三方jar.
  6. Android(安卓)view手势缩放与移动
  7. android截屏简单引用
  8. android handler正确写法
  9. Android(安卓)studio引用包冲突

随机推荐

  1. 阿里android面试准备与题目整理
  2. Android onTouchEvent, onClick及onLongC
  3. Android开发中阴影效果的实现
  4. 【Android】Android NDK入门
  5. Android(安卓)studio中build.gradle文件
  6. Android通过USB与PC通信
  7. Android中使用ant混淆编译
  8. Android多点触控技术
  9. Android:从零开始打造自己的深度链接库(四):D
  10. android根据屏幕尺寸区分设备类型,phone或