WeakReference在Handler中的应用
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却无法回收的情况。
所以解决这个警告就有几种方法:
一:将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;
}
}
}
}
转自:https://my.oschina.net/u/1177694/blog/523922
WeakReference在Handler中的应用的更多相关文章
- handler.post 为什么要将thread对象post到handler中执行呢?
转载网址:http://www.cnblogs.com/crazypebble/archive/2011/03/23/1991829.html在Android中使用Handler和Thread线程执行 ...
- asp.net Handler中的IsReusable属性及在Handler中使用Session
大家在用HttpHandler的时候,一般都会有两个大的疑问(当然,前提是你有钻研精神的话,呵呵) 1. IsReusable到底什么意思? 老实说,这个属性很多人都感兴趣,但搞懂的人确实不多.MSD ...
- [翻译]在asp.net core2.0 OpenID Connect Handler中丢失了声明(CLaims)?
注:这是一篇翻译,来自这里.这篇文章讲述了在asp.net core2.0中使用openid connect handler的过程中解析不到你想要的claim时,你可以参考这篇文章. Missing ...
- 转:handler.post 为什么要将thread对象post到handler中执行呢?
转载网址:http://blog.csdn.net/fei0724/article/details/8664462在Android中使用Handler和Thread线程执行后台操作 对于线程的控制,我 ...
- 处理handler中的内存泄漏
package de.bvb.test; import android.app.Activity; import android.os.Bundle; import android.os.Handle ...
- WeakReference 在android中的应用
转:http://my.oschina.net/u/1177694/blog/523922 首先我们来看一段代码 public class AutoActivity extends Activity ...
- android中handler中 obtainmessge与New message区别
obtainmessage()是从消息池中拿来一个msg 不需要另开辟空间new new需要重新申请,效率低,obtianmessage可以循环利用: //use Handler.obtainMess ...
- 关于Handler中Message的创建问题
Message用来定义一个包含任意数据的消息对象,这个消息对象是可以被发送给Handler处理的. 我们最好通过Message.obtain()和Handler.obtatinMessage()来得到 ...
- BaseHandler的封装, 处理handler中的内存泄漏
package de.bvb.study.common; /** * 用于规范 Message.what此属性,避免出现魔法数字 */ public final class What { public ...
随机推荐
- 深入理解javascript中的动态集合——NodeList、HTMLCollection和NamedNodeMap
× 目录 [1]NodeList [2]HTMLCollection [3]NamedNodeMap[4]注意事项 前面的话 一说起动态集合,多数人可能都有所了解.但是,如果再深入些,有哪些动态集合, ...
- ASP.NET WebAPi之断点续传下载(中)
前言 前情回顾:上一篇我们遗留了两个问题,一个是未完全实现断点续传,另外则是在响应时是返回StreamContent还是PushStreamContent呢?这一节我们重点来解决这两个问题,同时就在此 ...
- 哪些HTML5特性值得期待
首先大家可以看一下<HTML5程序设计(第二版)>最后一章关于HTML5未来展望.地址:http://www.ituring.com.cn/article/1690?q=html5%E6% ...
- 细说gulp
一.概述&安装 Gulp,简而言之,就是前端自动化开发工具,利用它,我们可以提高开发效率. 比如: 1. 压缩js 2. 压缩css 3. 压缩less 4. 压缩图片 等等… 我们完 ...
- eclipse导入项目Archive for required library cannot be read or is not a valid ZIP file
原因 :部分文件毁坏. 解决办法:1. 在eclipse中运行maven clean install 2. 报错,找到报错的文件物理删除,然后重新运行maven clean install 3. 循 ...
- java多线程--线程池的使用
程序启动一个新线程的成本是很高的,因为涉及到要和操作系统进行交互,而使用线程池可以很好的提高性能,尤其是程序中当需要创建大量生存期很短的线程时,应该优先考虑使用线程池. 线程池的每一个线程执行完毕后, ...
- (十二) WebGIS中矢量图层的设计
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.前言 在前几章中我们已经了解了什么是矢量查询.屏幕坐标与地理坐标之 ...
- 实现一个纵向排列的 ListBox ,并具有操作按钮
需要实现的效果如下: 要想把 ListBox 的内容纵向显示很简单,只需把 ListBox 的内容控件为 WrapPanel 就可以了: <ListBox.ItemsPanel> < ...
- GUI 和 GUILayout 的区别
GUI 和 GUILayout 的区别 A~ GUI是Unity中的基础控件类,其中包含了常用的GUI控件,列如Button,Label,PasswordField,slider,Window等等~ ...
- Visual Studio 2013 Unit Test Project App.config文件设置方法
开放中经常会要做单元测试,新的项目又没有单元测试项目,怎么才能搭建一个单元测试项目呢? 下面跟我四步走,如有错误之处,还请指正! 1.添加项目 2.添加配置文件 新建app.config文件,注意不是 ...