欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android 优化Handler防止内存泄露

程序员文章站 2024-02-12 12:36:58
android 优化handler防止内存泄露 demo描述:   handler可能导致的内存泄露及其优化   ...

android 优化handler防止内存泄露

demo描述: 

 handler可能导致的内存泄露及其优化    

  1 关于常见的handler的用法但是可能导致内存泄露 

  2 优化方式请参考betterhandler和betterrunnable的实现

package cc.cc; 
 
import java.lang.ref.weakreference; 
import android.os.bundle; 
import android.os.handler; 
import android.os.message; 
import android.app.activity; 
/** 
 * demo描述: 
 * handler可能导致的内存泄露及其优化 
 * 
 * 1 关于常见的handler的用法但是可能导致内存泄露 
 *  请参考方法inithandler() 
 * 2 优化方式请参考betterhandler和betterrunnable的实现 
 *  
 *
 * 
 */ 
public class mainactivity extends activity { 
  private handler mhandler; 
  @override 
  protected void oncreate(bundle savedinstancestate) { 
    super.oncreate(savedinstancestate); 
    setcontentview(r.layout.main); 
  } 
   
   
  /** 
   * 常见的handler的用法但是可能导致内存泄露 
   * 
   * 比如在旋转屏幕时该activity重新绘制. 
   * 但是因为mhandler发送了一个延迟消息,所以消息队列持有mhandler对象 
   * 又由于new runnable(){}持有外部类mainactivity的引用 
   * 所以activity所占内存并不能向期望的那样被回收,这样就可能会造成内存泄漏. 
   * 
   * 这个例子中handler的延迟时间比较久有20s,有点极端了,一般不会这么干; 
   * 这里只是为了更好地说明这个问题就这么写代码了。 
   * 
   */ 
  private void inithandler() { 
    mhandler = new handler() { 
      @override 
      public void handlemessage(message msg) { 
        super.handlemessage(msg); 
      } 
    }; 
 
    // ......doing something 
    // ......doing something 
    // ......doing something 
 
    // 发送延迟消息 
    mhandler.postdelayed(new runnable() { 
      @override 
      public void run() { 
 
      } 
    }, 1000 * 20); 
  } 
   
   
   
  /** 
   * 以下为优化方式 
   * 1 在此处把betterhandler和betterrunnable都设计为静态类, 
   * 这样它们就不会持有外部类的引用了. 
   * 2 在betterhandler中利用weakreference持有activity. 
   * 常听说:"如果一个对象具有弱引用,那么当gc线程扫描的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存" 
   * 其实准备地说应该是"如果一个对象只具有弱引用.........",即仅有弱引用而不存在对其的强引用才会将其回收. 
   * 那么此处对activity采用了弱引用,会不会导致该activity被回收呢? 
   * 答案是否定的。因为此处的activity还在显示界面,当然存在其他对象对它的强引用。所以不会对其回收。 
   *  
   * 经过这样的优化,当旋转屏幕时需要销毁原activity时;消息队列持有handler对象.但此时handler对象不再持有activity的引用. 
   * 所以系统会回收该activity所占内存.所以在handlemessage()中处理消息时需要判断activity是否为空. 
   * 比如此处20秒后才处理消息 这个时候activity为空. 
   */ 
  private static class betterhandler extends handler{ 
    private final weakreference<activity> activityweakreference; 
    public betterhandler(activity activity){ 
      activityweakreference=new weakreference<activity>(activity); 
    } 
    @override 
    public void handlemessage(message msg) { 
      super.handlemessage(msg); 
      if (activityweakreference.get()!=null) { 
        //.....handle message 
      } else { 
        system.out.println("activity==null"); 
      } 
    } 
  } 
   
  //同样采用静态内部类 
  private static class betterrunnable implements runnable{ 
    @override 
    public void run() { 
      // ......doing something 
    } 
     
  } 
   
  //发送延迟消息 
  private void sendmessage(){ 
    betterhandler betterhandler=new betterhandler(mainactivity.this); 
    betterhandler.postdelayed(new betterrunnable(), 1000 * 20); 
  } 
   
 
} 

如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!