匿名内部类引起的内存泄露——Handler和Thread

原因:匿名内部类会持有外部类的引用,当内部类进行延时操作的时候,如果外部类是Activity,那么在执行destroy后,并不会被销毁,从而导致内存泄漏。

Handler:

解决方案:

1.改为静态内部类(静态内部类不持有外部类的引用)+弱引用

private static MyHandler extends Handler {
        @Override
        public void handleMessage(Message msg)
       {
            //TODO handle message...
        }
 };

但是,发现不能持有外部引用,就不能调用外部类方法,因此我们内部改成持有外部类的弱引用。

public class MainActivity extends Activity {

  /**
   * Instancesof static inner classes do not hold an implicit
   * referenceto their outer class.
   */
  private static class MyHandler extends Handler {
    private final WeakReference<MainActivity> mActivity;

    public MyHandler(MainActivity activity) {
      mActivity= new WeakReference<MainActivity>(activity);
    }

    @Override
    public void handleMessage(Message msg) {
          MainActivity activity = mActivity.get();
      if(activity != null) {
        // ...
      }
    }
  }

2.静态Runnable,避免对外部类引用

private static final Runnable sRunnable = new Runnable() {
   @Override
   publicvoid run() {}
};

// Post amessage and delay its execution for 10 minutes.
mHandler.postDelayed(sRunnable, 60 * 10 * 1000);

Thread:

1.改为静态内部Thread,而且要在合适的时候结束,不能每次进入activity都起一个Thread

public class MainActivity extends Activity {
  privateMyThread mThread;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   exampleThree();
  }

  private void exampleThree() {
    mThread =new MyThread();
   mThread.start();
  }

  /**
   * Staticinner classes don't hold implicit references to their
   * enclosingclass, so the Activity instance won't be leaked across
   *configuration changes.
   */
  private static class MyThread extends Thread {
    private boolean mRunning = false;

    @Override
    public void run() {
      mRunning= true;
      while (mRunning) {
       SystemClock.sleep(1000);
      }
    }

    public void close() {
      mRunning= false;
    }
  }

  @Override
  protectedvoid onDestroy() {
   super.onDestroy();
   mThread.close();
  }
}
时间: 2024-11-09 09:50:34

匿名内部类引起的内存泄露——Handler和Thread的相关文章

Android Handler内存泄露

前言 在Android开发中,使用Handler的地方很多,大致通常写法如下: private Handler handler = new Handler() { public void handleMessage(android.os.Message msg) { if (msg.what == 1) { mAdapter.notifyDataSetChanged(); } }};这段代码看似没什么问题,但是里面却有一个警告,警告信息如下: This Handler class should

Andoid内存泄露

1 android 内存泄露是因为分配的内存回收失败 public static LocalHelper getInstance(Context context) { if (instance==null){ instance = new LocalHelper(context); } return instance;} 如果在contenx 传一个Activity 那么在Acitivty finish之后是无法对activity 进行回收的因为 静态实例会对activity继续引用, 这时候

彻底搞懂 Java 内存泄露

Java内存回收方式 Java判断对象是否可以回收使用的而是可达性分析算法. 在主流的商用程序语言中(Java和C#),都是使用可达性分析算法判断对象是否存活的.这个算法的基本思路就是通过一系列名为"GC Roots"的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的,下图对象object5, object6, object7虽然有互相判断,但它们到GC Roo

Android内存泄露分析和处理

什么是内存泄露 Java使用有向图机制,通过GC自动检查内存中的对象,如果GC发现一个或一组对象为不可到达状态,则将该对象从内存中回收.也就是说,一个对象不被任何引用所指向,则该对象会在被GC发现的时候被回收. 内存泄露的原因 1.资源对象没关闭造成的内存泄漏 资源性对象比如 (Cursor,File文件等)往往都用了一些缓冲,我们在不使用的时候,应该及时关闭它们,以便它们的缓冲及时回收内存.它们的缓冲不仅存在于 java虚拟机内,还存在于java虚拟机外.如果我们仅仅是把它的引用设置为null

Android中Handler引起的内存泄露

在Android常用编程中,Handler在进行异步操作并处理返回结果时经常被使用.通常我们的代码会这样实现. 但是,其实上面的代码可能导致内存泄露,当你使用Android lint工具的话,会得到这样的警告 In Android, Handler classes should be static or leaks might occur, Messages enqueued on the application thread’s MessageQueue also retain their t

Android中使用Handler引发的内存泄露

转载请注明出处:http://blog.csdn.net/allen315410/article/details/43638373 本文翻译自:国外某位开发者的博客How to Leak a Context: Handlers & Inner Classes,英文可以的朋友可以直接点击原文查看. 在Android常用编程中,Handler在进行异步操作并处理返回结果时经常被使用.通常我们的代码会这样实现. public class SampleActivity extends Activity

Android 中 Handler 引起的内存泄露

在Android常用编程中,Handler在进行异步操作并处理返回结果时经常被使用.其实这可能导致内存泄露,代码中哪里可能导致内存泄露,又是如何导致内存泄露的呢?那我们就慢慢分析一下.http://www.jinhusns.com/Products/Download/?type=xcj 在Android常用编程中,Handler在进行异步操作并处理返回结果时经常被使用.通常我们的代码会这样实现. public class SampleActivity extends Activity {   

android内存优化-Activity, Thread引起的内存泄露0

Android编程中一个共同的困难就是协调Activity的生命周期和长时间运行的任务(task),并且要避免可能的内存泄露.思考下面Activity的代码,在它启动的时候开启一个线程并循环执行任务. 1 /** 2 * 一个展示线程如何在配置变化中存活下来的例子(配置变化会导致创 3 * 建线程的Activity被销毁).代码中的Activity泄露了,因为线程被实 4 * 例为一个匿名类实例,它隐式地持有外部Activity实例,因此阻止Activity 5 * 被回收. 6 */ 7 pu

Android 从java字节码告诉你 为什么Handler会造成内存泄露

很多人面试的时候,都知道Handler 极易造成内存泄露,但是有一些讲不出来为什么,好一点的 会告诉你looper msg 之类的,但是你再往下问 为什么msg持有handler handler为什么 持有activity'的引用的时候 他们就答不出来了.这里我通过几个简单的例子 和极少部分的源码 来帮助大家彻底理解这一个流程. 那首先 我们来看一个例子,首先定义1个外部类 一个内部类: 1 package com.test.zj; 2 3 public class OuterClass { 4