Android Handler leak分析及解决办法详解

 更新时间:2017年03月13日 10:14:55   投稿:lqh  
这篇文章主要介绍了Android Handler leak分析及解决办法详解的相关资料,需要的朋友可以参考下

Android Handler leak 分析及解决办法

 In Android, Handler classes should be static or leaks might occur, Messages enqueued on the application thread's MessageQueue also retain their target Handler. If the Handler is an inner class, its outer class will be retained as well. To avoid leaking the outer class, declare the Handler as a static nested class with a WeakReference to its outer class.

    在Android中,Handler类应该是静态的,否则,可能发生泄漏。在应用程序线程的MessageQueue中排队的Message对象 还保留他们的目标Handler。如果Handler是一个内部类(注:无论是匿名还是非匿名,匿名是比较常见用法),它的外部类将被保留(至于为什么, 请参考Java嵌套类相关说明)。为了避免泄漏外部类,声明一个Handler子类为静态内部类(注:这样就避免了Handler对象对外部类实例的自动引用),其内部持有一个对外部类对象的WeakReference。

    上面是HandlerLeak的详细解释,同时下划线部分也提供了解决方案的思路。我们需要再分析一下几个泄漏问题:(1) 排队中的Message对象对Handler的持有导致泄漏;(2)Handler对象对外部类(如Activity或Service)实例的强引用持 有。是由于这两个原因同时作用导致出现泄漏的可能。我们的解决方案可以从原因出发,清除这两个原因,就会比较完整的解决这个问题。

    方案:(1)针对第1个原因,在使用Handler的组件生命周期结束前清除掉MessageQueue中的发送给Handler的Message对象(例如在Activity或Service的onDestroy()中调用Handler的remove*方法);(2)针对第2个原因,Handler的实现类采用静态内部类的方式,避免对外部类的强引用,在其内部声明一个WeakReference引用到外部类的实例。

    关于Handler的remove*方法,这儿介绍一下(可以参考源码或文档)

removeCallbacks(Runnable r) ——清除r匹配上的Message。

removeCallbacks(Runnable r, Object token) ——清除r匹配且匹配token(Message.obj)的Message,token为空时,只匹配r。

removeCallbacksAndMessages(Object token) ——清除token匹配上的Message。

removeMessages(int what) ——按what来匹配

removeMessages(int what, Object object) ——按what来匹配

我们更多需要的是清除以该Handler为target的所有Message(包括Callback),那么调用如下方法即可

    handler.removeCallbacksAndMessages(null);

    最终代码像下面这样

package org.dragonboy.example;
 
import java.lang.ref.WeakReference;
 
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
 
/**
 * @author dragonboyorg@qq.com
 */
public class MyActivity extends Activity {
  private MyHandler mHandler;
 
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
 
    mHandler = new MyHandler(this);
  }
 
  @Override
  protected void onDestroy() {
    // Remove all Runnable and Message.
    mHandler.removeCallbacksAndMessages(null);
 
    super.onDestroy();
  }
 
  static class MyHandler extends Handler {
    // WeakReference to the outer class's instance.
    private WeakReference<myactivity> mOuter;
 
    public MyHandler(MyActivity activity) {
      mOuter = new WeakReference<myactivity>(activity);
    }
 
    @Override
    public void handleMessage(Message msg) {
      MyActivity outer = mOuter.get();
      if (outer != null) {
        // Do something with outer as your wish.
      }
    }
  }
}
</myactivity></myactivity>

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

相关文章

  • Android RadarView雷达图(蜘蛛网图)的实现代码

    Android RadarView雷达图(蜘蛛网图)的实现代码

    这篇文章主要介绍了Android RadarView雷达图(蜘蛛网图)的实现代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-03-03
  • monkeyrunner环境搭建及实例教程(3)

    monkeyrunner环境搭建及实例教程(3)

    这篇文章主要为大家详细介绍了monkeyrunner环境搭建及实例教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-11-11
  • Android自定义弹出框的方法

    Android自定义弹出框的方法

    这篇文章主要为大家详细介绍了Android自定义弹出框的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-06-06
  • adnroid已安装应用中检测某应用是否安装的代码实例

    adnroid已安装应用中检测某应用是否安装的代码实例

    这篇文章主要介绍了Android怎么检测一个应用是否安装的方法,大家参考使用吧
    2013-11-11
  • Android开发中Intent传递对象的方法分析

    Android开发中Intent传递对象的方法分析

    这篇文章主要介绍了Android开发中Intent传递对象的方法,结合实例分析了Intent传递对象所涉及的具体方法、实现步骤与相关注意事项,需要的朋友可以参考下
    2016-02-02
  • 捕获与解析Android NativeCrash

    捕获与解析Android NativeCrash

    Android 开发中,NE一直是不可忽略却又异常难解的一个问题,原因是这里面涉及到了跨端开发和分析,需要同时熟悉 Java,C&C++,并且需要熟悉 NDK开发,并且解决起来不像 Java异常那么明了,本文为了解决部分疑惑,将从NE的捕获,解析与还原等三个方面进行探索
    2021-06-06
  • Android编程实现从字符串中查找电话号码的方法

    Android编程实现从字符串中查找电话号码的方法

    这篇文章主要介绍了Android编程实现从字符串中查找电话号码的方法,涉及Android针对字符串的匹配与查找相关技巧,需要的朋友可以参考下
    2016-03-03
  • Android Selector和Shape的使用方法

    Android Selector和Shape的使用方法

    本文介绍下背景选择器、文字颜色选择器、背景渐变器的实现。结合Shape来实现背景渐变效果。或者只是以color代替drawable作为背景选择器的元素
    2013-06-06
  • Android 实现自定义圆形listview功能的实例代码

    Android 实现自定义圆形listview功能的实例代码

    这篇文章主要介绍了Android 实现自定义圆形listview功能的实例代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07
  • Flutter搞定宽高不统一布局开发的方法详解

    Flutter搞定宽高不统一布局开发的方法详解

    我们在开发移动端界面的时候,经常会遇到一组尺寸不一的组件需要作为同一组展示,所以本文就将利用Wrap组件搞定宽高不统一布局开发,需要的可以参考一下
    2023-06-06

最新评论