素材巴巴 > 程序开发 >

Android Handler内存泄露和不会ANR原因

程序开发 2023-09-18 08:14:02

1.handlee引发内存泄露Memory Leak

当不再需要某个实例后,这个对象却仍然被引用,不能被垃圾回收(Prevent from being bargage collected),这个情况就叫做内存泄露。

 

Handler使用不当很容易引起内存泄露,比如:

public class MainActivity extends Activity {

  private final Handler mHandler = new Handler(){

    @Override

      public void handleMessage(Message msg) {

            // ... 

      }

   }

}

这段代码可能导致内存泄露。Android Lint会提示以下信息:

In Android, Handler classes should be static or leaks might occur.

那么引发内存泄露的原因是什么呢?

①当一个Android应用程序启动的时候,Anroid框架为这个程序的主线程创建了一个Looper对象,用于处理Handler中的Message。Looper实现了一个简单的消息队列messagequeue,不断循环的处理其中的message。所有的应用程序框架的事件(比如Activity生命周期的调用,按钮的点击等)都被封装在这个Message对象里,然后被加入到Looper的Messagequeue,最后一个一个的处理这些Message。注意,Looper在整个应用程序的生命周期中一直存在。

②在主线程中实例化一个Handler对象的时候,就和它关联了主线程Looper的消息队列Messagequeue。被发送到这个消息队列的Message将保持对这个Handler对象的引用,这样框架就可以在处理这个Message的时候调用Handler.handleMessage(Message)来处理消息了。(也就是说,只要没有处理到这个Message,Handler就一直在队列中被引用)

③在Java中,非静态内部类和匿名内部类都隐式的保持了对外部类的引用。但是静态内部类不会有这个引用。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5a2f6Iqz6Iqz,size_20,color_FFFFFF,t_70,g_se,x_16

那么内存泄露到底在哪里呢?先看下面的例子:

public class MainActivity extends Activity {

  private final Handler mHandler = new Handler(){

    @Override

    public void handleMessage(Message msg) { 

        // ...

    }

  }

   @Override

   protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); 

    mHandler.postDelayed(new Runnable() {         

        @Over


标签:

素材巴巴 Copyright © 2013-2021 http://www.sucaibaba.com/. Some Rights Reserved. 备案号:备案中。