Android中。在使用到Handler的时候,假设按例如以下代码编写:

	private Handler handler;

	@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
handler = new Handler() { @Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
} }; handler.sendMessageDelayed(Message.obtain(), 60000); // just finish this activity
finish();
}

然后执行Android Lint工具会有一个内存泄露警告:

This Handler class should be static or leaks might occur (com.example.ta.MainActivity.1)

Issue: Ensures that Handler classes do not hold on to a reference to an outer class
Id: HandlerLeak

In Android, Handler classes should be static or leaks might occur. Messages enqueued on the application thread’s MessageQueue also retain their target Handler. If the Handler is an inner class, its outer class will be retained as well. To avoid leaking the outer class, declare the Handler as a static nested class with a WeakReference to its outer class.

原因是:

  1. 当Android应用启动的时候,会先创建一个应用主线程的Looper对象,Looper实现了一个简单的消息队列,一个一个的处理里面的Message对象。

    主线程Looper对象在整个应用生命周期中存在。

  2. 当在主线程中初始化Handler时,该Handler和Looper的消息队列关联。发送到消息队列的Message会引用发送该消息的Handler对象,这样系统能够调用 Handler#handleMessage(Message) 来分发处理该消息。

  3. 在Java中,非静态(匿名)内部类会引用外部类对象。而静态内部类不会引用外部类对象。

  4. 假设外部类是Activity。则会引起Activity泄露 。

当Activity finish后,延时消息会继续存在主线程消息队列中1分钟。然后处理消息。而该消息引用了Activity的Handler对象,然后这个Handler又引用了这个Activity。这些引用对象会保持到该消息被处理完。这样就导致该Activity对象无法被回收,从而导致了上面说的 Activity泄露。

要改动该问题,仅仅须要依照Lint提示的那样。把Handler类定义为静态就可以,然后通过WeakReference 来保持外部的Activity对象。

	private static class WebViewHandler extends Handler{

		public static final int what_pullRefreshCompleted = 1;

		private final WeakReference<WebActivity> mActivity;

		public WebViewHandler(WebActivity mActivity) {
super();
this.mActivity = new WeakReference<WebActivity>(mActivity);
} @Override
public void handleMessage(Message msg) {
if(mActivity.get() == null)
return;
switch(msg.what){
case what_pullRefreshCompleted:
if (mActivity.get().getmPullRefreshWebView() != null)//由于该Handler为static,所以我们通过调用方法来获取外部类属性
mActivity.get().getmPullRefreshWebView().refreshComplete();
break;
}
super.handleMessage(msg);
}
}

所以,在Activity中使用内部类的时候,须要时刻考虑您能否够控制该内部类的生命周期,假设不能够,则最好定义为静态内部类。

另外。再附上一个注意事项知识点,希望对大家实用:

不要持有 Context 的静态引用!

public class ExampleActivity extends Activity {

	//...
private static MyAccountInfo info;
//... @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//...
info = new MyAccountInfo(this);
//...
} }

上面这点代码。对于一个有丰富经验的人来,可能不会犯这种错误。

然后也会有非常多人会犯这种错误,一段看似没有问题的代码,实际上可能会给我们的应用带来麻烦。不要这样做,可能会出问题的。

假设 MyAccountInfo 通过它的构造函数保持一个指向Activity的引用,这个Activity将不会被垃圾回收(GC)。除非静态变量被从新分配到不同的Activity。

这是由于 info 是静态变量,而静态变量的内存是不会被回收,直到应用程序退出才回收。假设你正在试图做这种事情。你的代码非常有可能有严重的错误。依据实际逻辑须要换个写法吧。

注:从技术上说,你能够对一个Application Context进行静态变量引用而不引起内存泄露。但我不建议你这样做。

This Handler class should be static or leaks might occur,Handler和Context使用的注意事项!的更多相关文章

  1. Android“This Handler class should be static or leaks might occur”警告的处理方法

    此文属于转载! 最近用到handle在线程中改变UI,会跟给出“This Handler class should be static or leaks might occur”的警告,网上看了很多解 ...

  2. Android - This Handler class should be static or leaks might occur.

    今天学习了使用 HTTP协议,从Android客户端往Tomcat服务器端以GET发送请求,途中无意中发现自己写的Handler类被Android提示:This Handler class shoul ...

  3. This Handler class should be static or leaks might occur(null) 解决办法 (转)

    原文链接:http://blog.csdn.net/wuleihenbang/article/details/17126371 首先解释下这句话This Handler class should be ...

  4. This Handler class should be static or leaks might occur Android

    首先解释下这句话This Handler class should be static or leaks might occur,大致意思就是说:Handler类应该定义成静态类,否则可能导致内存泄露 ...

  5. android之lint警告This Handler class should be static or leaks might occur

    更新到adt2.0的开发者们可能会在handler上发现这么一条警告:This Handler class should be static or leaks might occur . 首先在ADT ...

  6. Handler classes should be static or leaks might occur

    http://droidyue.com/blog/2014/12/28/in-android-handler-classes-should-be-static-or-leaks-might-occur ...

  7. 85、android handler的警告Handler Class Should be Static or Leaks Occur

    转载:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1106/1922.html 在使用Handler更新UI的时候,我是这样写 ...

  8. 【Android】[转] Android Handler应设为static

    android开发中,使用Lint检测时会提示这么一句话 : This Handler class should be static or leaks might occur.意为handler应用s ...

  9. Android Handler的使用示例:结合源码理解Android Handler机制(一)

    什么是Handler? Android 的官方解释: 文档分节1:A Handler allows you to send and process Message and Runnable objec ...

随机推荐

  1. maven 之dependencyManagement 和 pluginManagement

    一个大中型Java项目中,一般由若干个module组成,各个module各司其职,担任整个工程中不同角色.大多数情况下,大多数module都会用到相同的jar包,或者插件.如果每个module中都引入 ...

  2. FT项目开发技术点(三)

    1.eclipse中开发的web项目怎么放到tomcat中? 记得开始学习Java Web的时候,首先用的是Eclipse开发,但是有一个问题始终没有弄明白,做好的Web项目是如何发布到Tomcat服 ...

  3. Peter Norvig:学习在于挑战和重复

    黄小非译注(本文来自伯乐在线):本文作者Peter Norvig目前任职于Google,其职位是研究主管(Director of  Research). Peter Norvig是享誉世界的计算机科学 ...

  4. 《Windows核心编程》第八章——用户模式下的线程同步

    下面起了两个线程,每个对一个全局变量加500次,不假思索进行回答,会认为最后这个全局变量的值会是1000,然而事实并不是这样: #include<iostream> #include &l ...

  5. 跟我学Spring3(9.2):Spring的事务之事务管理器

    原文出处: 张开涛9.2.1 概述 Spring框架支持事务管理的核心是事务管理器抽象,对于不同的数据访问框架(如Hibernate)通过实现策略接口PlatformTransactionManage ...

  6. 【BZOJ】【2595】【WC2008】游览计划

    Orz zky神犇http://blog.csdn.net/iamzky/article/details/42029921 spfa的灵活应用!(好像是求了一个叫做斯坦纳树的东西……) o(︶︿︶)o ...

  7. quickcocos2dx framework环境变 fatal error C1083: 无法打开源文件:“.Box2D/Dynamics/b2World.h”: No such file or d

      : fatal error C1083: 无法打开源文件:".Box2D/Dynamics/b2World.h": No such file or directory 解决方法 ...

  8. 用C语言获取任意文件的长度(可能大于2GB)

    用C语言获取文件长度的常见思路是: 打开文件后用 fseek() 函数把文件位置指针移动到文件的末尾,用 ftell() 获得这时位置指针距文件头的字节数,这个字节数就是文件的长度.但是这样做也会受到 ...

  9. IOS NSString 用法详解

    [cpp]  view plain copy   //NSString 操作均不改变自身值 //构建字符串 NSString *szTmp = @"A string";       ...

  10. Cognos由于JAVA_HOME冲突引起的错误假象

    Cognos的安装和配置并不是很复杂,但是对于初次安装的用户来说,还是要注意一些细节,比如JDK问题,今天我们就来阐述一下这个问题 场景1: 作为一个开发人员,很多人是十八般武艺样样精通,难免已经在自 ...