This Handler class should be static or leaks might occur,Handler和Context使用的注意事项!
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: HandlerLeakIn 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.
原因是:
当Android应用启动的时候,会先创建一个应用主线程的Looper对象,Looper实现了一个简单的消息队列,一个一个的处理里面的Message对象。
主线程Looper对象在整个应用生命周期中存在。
当在主线程中初始化Handler时,该Handler和Looper的消息队列关联。发送到消息队列的Message会引用发送该消息的Handler对象,这样系统能够调用 Handler#handleMessage(Message) 来分发处理该消息。
在Java中,非静态(匿名)内部类会引用外部类对象。而静态内部类不会引用外部类对象。
假设外部类是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使用的注意事项!的更多相关文章
- Android“This Handler class should be static or leaks might occur”警告的处理方法
此文属于转载! 最近用到handle在线程中改变UI,会跟给出“This Handler class should be static or leaks might occur”的警告,网上看了很多解 ...
- Android - This Handler class should be static or leaks might occur.
今天学习了使用 HTTP协议,从Android客户端往Tomcat服务器端以GET发送请求,途中无意中发现自己写的Handler类被Android提示:This Handler class shoul ...
- This Handler class should be static or leaks might occur(null) 解决办法 (转)
原文链接:http://blog.csdn.net/wuleihenbang/article/details/17126371 首先解释下这句话This Handler class should be ...
- This Handler class should be static or leaks might occur Android
首先解释下这句话This Handler class should be static or leaks might occur,大致意思就是说:Handler类应该定义成静态类,否则可能导致内存泄露 ...
- 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 ...
- 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 ...
- 85、android handler的警告Handler Class Should be Static or Leaks Occur
转载:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1106/1922.html 在使用Handler更新UI的时候,我是这样写 ...
- 【Android】[转] Android Handler应设为static
android开发中,使用Lint检测时会提示这么一句话 : This Handler class should be static or leaks might occur.意为handler应用s ...
- Android Handler的使用示例:结合源码理解Android Handler机制(一)
什么是Handler? Android 的官方解释: 文档分节1:A Handler allows you to send and process Message and Runnable objec ...
随机推荐
- poj 1028 Web Navigation(模拟)
题目链接:http://poj.org/problem? id=1028 Description Standard web browsers contain features to move back ...
- 在EntityFramework6中管理DbContext的正确方式——1考虑的关键点(外文翻译)
(译者注:使用EF开发应用程序的一个难点就在于对其DbContext的生命周期管理,你的管理策略是否能很好的支持上层服务 使用独立事务,使用嵌套事务,并行执行,异步执行等需求? Mehdi El Gu ...
- Extjs 事件监听
<!DOCTYPE html> <html> <head> <title>hello-extjs</title> <meta http ...
- 算法:冒泡排序(Bubble Sort)、插入排序(Insertion Sort)和选择排序(Selection Sort)总结
背景 这两天温习了 5 中排序算法,之前也都看过它们的实现,因为没有深入分析的缘故,一直记不住谁是谁,本文就记录一下我学习的一些心得. 三种排序算法可以总结为如下: 都将数组分为已排序部分和未排序部分 ...
- Log4j输出格式控制
参数说明例子 %c 列出logger名字空间的全称,如果加上{<层数>}表示列出从最内层算起的指定层数的名字空间 log4j配置文件参数举例 输出显示媒介 假设当前logger名字空间是& ...
- uva 1025 A Spy in the Metro 解题报告
A Spy in the Metro Time Limit: 3000MS 64bit IO Format: %lld & %llu Submit Status uDebug Secr ...
- ubuntu下mongodb启动脚本
run-mongodb.sh #!/bin/bash mongod --dbpath /usr/local/mongodb/data1 --logpath /usr/local/mongodb/log ...
- OpenCV学习(16) 细化算法(4)
本章我们学习Rosenfeld细化算法,参考资料:http://yunpan.cn/QGRjHbkLBzCrn 在开始学习算法之前,我们先看下连通分量,以及4连通性,8连通性的概念: http://w ...
- Android中intent如何传递自定义数据类型
转载自:http://www.cnblogs.com/GoAhead/archive/2012/07/16/2593868.html 大家好,好久不见,今天要给大家讲一下Android中Intent中 ...
- Android UI-底部旋转菜单栏
以前都是说每逢佳节倍思亲,现在的工作状态是每到周末倍亲切,年底真的是加班加的没完没了的,也没时间写博客,也没时间学习,周末闲来无事看到一个比较有意思的旋转菜单,没事自己实战了一下感觉还不错,代码倒是没 ...