zoukankan      html  css  js  c++  java
  • 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);

  • 相关阅读:
    文件同步
    Renesas PPP Mode
    PYTHON 常用API ***
    Python DB
    Python VIL Realse
    C BIN加密
    Python VIL Service Bin
    Python 定期检查Build_setting的编译情况
    Python 字串处理
    IP分片(IP Fragment)
  • 原文地址:https://www.cnblogs.com/ly570/p/11498554.html
Copyright © 2011-2022 走看看