温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

在Android应用中使用Handler时出现 leak如何解决

发布时间:2020-11-27 15:45:12 来源:亿速云 阅读:217 作者:Leah 栏目:移动开发

这篇文章给大家介绍在Android应用中使用Handler时出现 leak如何解决,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

    在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应用中使用Handler时出现 leak如何解决就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI