转:http://my.oschina.net/u/1177694/blog/523922

首先我们来看一段代码

public class AutoActivity extends Activity {

	Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) { };
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_auto);
}
}

上面这段代码没有什么问题,但是在handler对象创建的时候却会报警告:This Handler class should be static or leaks might occur意思是:Handler

类应该为static类型,否则可能会造成内存泄漏。为什么会造成这种情况呢?这种情况就是由于android的特殊机制造成的:当一个android主线程被创

建的时候,同时会有一个Looper对象被创建,而这个Looper对象会实现一个MessageQueue(消息队列),当我们创建一个handler对象时,而handler的

作用就是放入和取出消息从这个消息队列中,每当我们通过handler将一个msg放入消息队列时,这个msg就会持有一个handler对象的引用。因此当

Activity被结束后,这个msg在被取出来之前,这msg会继续存活,但是这个msg持有handler的引用,而handler在Activity中创建,会持有Activity的引用,

因而当Activity结束后,Activity对象并不能够被gc回收,因而出现内存泄漏。

这个根本原因就是:Activity在被结束之后,MessageQueue并不会随之被结束,如果这个消息队列中存在msg,则导致持有handler的引用,但是又

由于Activity被结束了,msg无法被处理,从而导致永久持有handler对象,handler永久持有Activity对象,于是发生内存泄漏。但是为什么为static类型就

会解决这个问题呢?因为在java中所有非静态的对象都会持有当前类的强引用,而静态对象则只会持有当前类的弱引用。声明为静态后,handler将会持

有一个Activity的弱引用,而弱引用会很容易被gc回收,这样就能解决Activity结束后,gc却无法回收的情况。(至于为什么强引用不能够被gc自动回收,而

弱引用对象为什么会被gc回收,可以自行去google)。

所以解决这个警告就有几种方法:

一:将hanlder对象声明为静态的对象。

二:使用静态内部类,通过WeakReference实现对Activity的弱引用。具体实现看以下代码:

public class AutoActivity extends Activity {

	MyHandler handler = new MyHandler(this);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_auto);
} static class MyHandler extends Handler{
WeakReference<AutoActivity> mactivity; public MyHandler(AutoActivity activity){
mactivity = new WeakReference<AutoActivity>(activity);
} @Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 100:
//在这里面处理msg
//通过mactivity.get()获取Activity的引用(即上下文context)
break;
default:
break;
}
}
}
}

WeakReference 在android中的应用的更多相关文章

  1. Android中使用Handler造成内存泄露的分析和解决

    什么是内存泄露?Java使用有向图机制,通过GC自动检查内存中的对象(什么时候检查由虚拟机决定),如果GC发现一个或一组对象为不可到达状态,则将该对象从内存中回收.也就是说,一个对象不被任何引用所指向 ...

  2. 系统剖析Android中的内存泄漏

    [转发]作为Android开发人员,我们或多或少都听说过内存泄漏.那么何为内存泄漏,Android中的内存泄漏又是什么样子的呢,本文将简单概括的进行一些总结. 关于内存泄露的定义,我可以理解成这样 没 ...

  3. Android中使用Handler造成内存泄露

    1.什么是内存泄露? Java使用有向图机制,通过GC自动检查内存中的对象(什么时候检查由虚拟机决定),如果GC发现一个或一组对象为不可到达状态,则将该对象从内存中回收.也就是说,一个对象不被任何引用 ...

  4. Android中插件开发篇之----动态加载Activity(免安装运行程序)

    一.前言 又到周末了,时间过的很快,今天我们来看一下Android中插件开发篇的最后一篇文章的内容:动态加载Activity(免安装运行程序),在上一篇文章中说道了,如何动态加载资源(应用换肤原理解析 ...

  5. Android 进阶 Android 中的 IOC 框架 【ViewInject】 (下)

    上一篇博客我们已经带大家简单的吹了一下IoC,实现了Activity中View的布局以及控件的注入,如果你不了解,请参考:Android 进阶 教你打造 Android 中的 IOC 框架 [View ...

  6. Android 中 Handler 引起的内存泄露

    在Android常用编程中,Handler在进行异步操作并处理返回结果时经常被使用.其实这可能导致内存泄露,代码中哪里可能导致内存泄露,又是如何导致内存泄露的呢?那我们就慢慢分析一下.http://w ...

  7. 在Android中使用并发来提高速度和性能

    Android框架提供了很实用的异步处理类.然而它们中的大多数在一个单一的后台线程中排队.当你需要多个线程时你是怎么做的? 众所周知,UI更新发生在UI线程(也称为主线程).在主线程中的任何操作都会阻 ...

  8. Android中的Apk的加固(加壳)原理解析和实现

    一.前言 今天又到周末了,憋了好久又要出博客了,今天来介绍一下Android中的如何对Apk进行加固的原理.现阶段.我们知道Android中的反编译工作越来越让人操作熟练,我们辛苦的开发出一个apk, ...

  9. Android 进阶 教你打造 Android 中的 IOC 框架 【ViewInject】 (下)

    上一篇博客我们已经带大家简单的吹了一下IoC,实现了Activity中View的布局以及控件的注入,如果你不了解,请参考:Android 进阶 教你打造 Android 中的 IOC 框架 [View ...

随机推荐

  1. Mybatis学习4——核心文件sqlMapperConfig.xml属性

    1.外部文件jdbc.properties jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/mybatis ...

  2. python3自动生成并运行bat批处理,并重定向输入消除黑窗口

    #coding:utf-8import os #bat文件的内容(temp.bat)bat_name='temp.bat's1='''echo offipconfigecho Hello world! ...

  3. 恺撒密码 I Python实现

    '''恺撒密码 I描述凯撒密码是古罗马凯撒大帝用来对军事情报进行加解密的算法,它采用了替换方法对信息中的每一个英文字符循环替换为字母表序列中该字符后面的第三个字符,即,字母表的对应关系如下:原文:A ...

  4. delphi 连接DBF

    delphi 连接DBF 使用 DBF 文件时,文件夹表示数据库,单个 DBF 文件表示表 1.BDE,已淘汰 table1.Databasename:=dbdir;//设置库路径table1.Tab ...

  5. delphi RTTI 四 获取类属性列表

    delphi RTTI 四 获取类属性列表 GetPropList(btn1.ClassInfo, tkAny, PropList) PropCount := GetTypeData(btn1.Cla ...

  6. Navicat for MySQL 安装和破解(完美)

    Navicat for MySQL 安装软件和破解补丁: 链接:https://pan.baidu.com/s/1oKcErok_Ijm0CY9UjNMrnA   密码:4xb1 navicat fo ...

  7. 详述 IntelliJ IDEA 插件的安装及使用方法

    首先,进入插件安装界面: Mac:IntelliJ IDEA -> Preferences -> Plugins; Windows:File -> Settings -> Pl ...

  8. Spring Cloud Config中文文档

    https://springcloud.cc/spring-cloud-config.html 目录 快速开始 客户端使用 Spring Cloud Config服务器 环境库 健康指标 安全 加密和 ...

  9. Delphi 三层TDataSetProvider

    在Delphi想使用三层架构或者使用TClientDataSet控件,一般都需要引用TDataSetProvider控件,现对TDataSetProvider控件的Options属性值做一个简单的分析 ...

  10. 使用py2exe转换python文件为可执行程序

    py2exe可以将python脚本转换成在Windows上的可独立执行.exe程序的工具.可以让Python脚本在没有安装python工具的Windows系统上运行,方便脚本共享. 操作环境 pyth ...