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

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

成都创新互联是少有的做网站、成都网站建设、营销型企业网站、微信平台小程序开发、手机APP,开发、制作、设计、买链接、推广优化一站式服务网络公司,自2013年创立以来,坚持透明化,价格低,无套路经营理念。让网页惊喜每一位访客多年来深受用户好评

先看一组简单的代码

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 mActivity;      public MyHandler(SampleActivity activity) {       mActivity = new WeakReference(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引起的内存泄露怎么解决”有了更深的了解,不妨来实际操作一番吧!这里是创新互联网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!


当前标题:Handler引起的内存泄露怎么解决
文章源于:http://azwzsj.com/article/gdcsdh.html