热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

Android优化Handler防止内存泄露

这篇文章主要介绍了Android优化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 activityWeakReference; 
    public BetterHandler(Activity activity){ 
      activityWeakReference=new WeakReference(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); 
  } 
   
 
} 

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


推荐阅读
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 栈和队列的共同处和不同处
    本文主要介绍了栈和队列的共同处和不同处。栈和队列都是由几个数据特性相同的元素组成的有限序列,也就是线性表。队列是限定仅在表的一端插入元素、在另一端删除元素的线性表,遵循先进先出的原则。栈是限定仅在表尾进行插入或删除操作的线性表,遵循后进先出的原则。 ... [详细]
  • Android工程师面试准备及设计模式使用场景
    本文介绍了Android工程师面试准备的经验,包括面试流程和重点准备内容。同时,还介绍了建造者模式的使用场景,以及在Android开发中的具体应用。 ... [详细]
  • 本文介绍了在Android开发中使用软引用和弱引用的应用。如果一个对象只具有软引用,那么只有在内存不够的情况下才会被回收,可以用来实现内存敏感的高速缓存;而如果一个对象只具有弱引用,不管内存是否足够,都会被垃圾回收器回收。软引用和弱引用还可以与引用队列联合使用,当被引用的对象被回收时,会将引用加入到关联的引用队列中。软引用和弱引用的根本区别在于生命周期的长短,弱引用的对象可能随时被回收,而软引用的对象只有在内存不够时才会被回收。 ... [详细]
  • 本文介绍了如何使用PHP向系统日历中添加事件的方法,通过使用PHP技术可以实现自动添加事件的功能,从而实现全局通知系统和迅速记录工具的自动化。同时还提到了系统exchange自带的日历具有同步感的特点,以及使用web技术实现自动添加事件的优势。 ... [详细]
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
  • 本文介绍了栈和队列的区别及其特点。栈是一种先进后出的线性表,只能在表的一端进行插入和删除操作;队列是一种先进先出的线性表,只能在表的一端进行插入和在另一端进行删除操作。栈和队列是两种广泛使用的线性数据结构,它们的基本操作具有特殊性。栈的遍历需要遍历整个栈才能取出数据,并需要为数据开辟临时空间,而队列基于地址指针进行遍历,可以从头或尾部开始遍历,但不能同时遍历,且无需开辟临时空间。栈和队列在程序设计中具有重要应用。 ... [详细]
  • Linux的uucico命令使用方法及工作模式介绍
    本文介绍了Linux的uucico命令的使用方法和工作模式,包括主动模式和附属模式。uucico是用来处理uucp或uux送到队列的文件传输工具,具有操作简单快捷、实用性强的特点。文章还介绍了uucico命令的参数及其说明,包括-c或--quiet、-C或--ifwork、-D或--nodetach、-e或--loop、-f或--force、-i或--stdin、-I--config、-l或--prompt等。通过本文的学习,读者可以更好地掌握Linux的uucico命令的使用方法。 ... [详细]
  • 重入锁(ReentrantLock)学习及实现原理
    本文介绍了重入锁(ReentrantLock)的学习及实现原理。在学习synchronized的基础上,重入锁提供了更多的灵活性和功能。文章详细介绍了重入锁的特性、使用方法和实现原理,并提供了类图和测试代码供读者参考。重入锁支持重入和公平与非公平两种实现方式,通过对比和分析,读者可以更好地理解和应用重入锁。 ... [详细]
  • 本文介绍了操作系统的定义和功能,包括操作系统的本质、用户界面以及系统调用的分类。同时还介绍了进程和线程的区别,包括进程和线程的定义和作用。 ... [详细]
  • 一、什么是闭包?有什么作用什么是闭包闭包是定义在一个函数内部的函数,它可以访问父级函数的内部变量。当一个闭包被创建时,会关联一个作用域—— ... [详细]
  • 本文讨论了读书的目的以及学习算法的重要性,并介绍了两个算法:除法速算和约瑟夫环的数学算法。同时,通过具体的例子和推理,解释了为什么x=x+k序列中的第一个人的位置为k,以及序列2和序列3的关系。通过学习算法,可以提高思维能力和解决问题的能力。 ... [详细]
author-avatar
7-好
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有