Handler引起的内存泄露怎么解决

发布时间:2021-12-24 16:05:12 作者:iii
来源:亿速云 阅读:137

本篇内容主要讲解“Handler引起的内存泄露怎么解决”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Handler引起的内存泄露怎么解决”吧!

先看一组简单的代码

public class SampleActivity extends Activity {    private final Handler mHandler = new Handler() {     @Override     public void handleMessage(Message msg) {       // ...      }   } }

当我们这样写在一个Activity中时,Android Lint会提示我们这样一个  warning: In Android, Handler classes should be static or  leaks might occur.
意思说:在Android中,Handler  类应该是静态的否则可能发生泄漏。

为什么会是这样呢?

了解一下Handler

  1. 当Android程序***次创建的时候,在主线程同时会创建一个Looper对象。Looper实现了一个简单的消息队列,一个接着一个处理Message对象。程序框架所有主要的事件(例如:屏幕上的点击时间,Activity生命周期的方法等等)都包含在Message对象中,然后添加到Looper的消息队列中,一个一个处理。主线程的Looper存在整个应用程序的生命周期内。

  2. 当一个Handler对象在主线程中创建的时候,它会关联到Looper的  message queue  。Message添加到消息队列中的时候Message会持有当前Handler引用,当Looper处理到当前消息的时候,会调用Handler#handleMessage(Message).

  3. java中,no-static的内部类会 隐式的  持有当前类的一个引用。static的类则没有。

在什么地方引起了内存的泄露呢?再看看下面一段代码

public class SampleActivity extends Activity {    private final Handler mHandler = new Handler() {     @Override     public void handleMessage(Message msg) {       // ...     }   }    @Override   protected void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);      // 发送一个10分钟后执行的一个消息     mHandler.postDelayed(new Runnable() {       @Override       public void run() { }     }, 600000);      // 结束当前的Activity     finish();   } }

Activity结束后,在 Message queue  处理这个Message之前,它会持续存活着。这个Message持有Handler的引用,而Handler有持有Activity(SampleActivity)的引用,这个Activity所有的资源,在这个消息处理之前都不能也不会被回收,所以发生了内存泄露。

解决办法,看下面一段代码

public class SampleActivity extends Activity {    /**    * 使用静态的内部类,不会持有当前对象的引用    */   private static class MyHandler extends Handler {     private final WeakReference<SampleActivity> mActivity;      public MyHandler(SampleActivity activity) {       mActivity = new WeakReference<SampleActivity>(activity);     }      @Override     public void handleMessage(Message msg) {       SampleActivity activity = mActivity.get();       if (activity != null) {         // ...       }     }   }    private final MyHandler mHandler = new MyHandler(this);    /**    * 使用静态的内部类,不会持有当前对象的引用    */   private static final Runnable sRunnable = new Runnable() {       @Override       public void run() { }   };    @Override   protected void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);      //  发送一个10分钟后执行的一个消息     mHandler.postDelayed(sRunnable, 600000);      // 结束     finish();   } }

到此,相信大家对“Handler引起的内存泄露怎么解决”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

推荐阅读:
  1. 如何解决Tensorflow内存泄露的问题
  2. C#中如何解决定时器保活机制引起的内存泄露问题

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

handler

上一篇:Kubernetes-dashboard+Heapster+InfluxDB+Grafana的示例分析

下一篇:linux中如何删除用户组

相关阅读

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

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