从Android Handler内部类到WeakReference的知识关联
Handler:
普通使用方法:
Handler用于处理和从队列MessageQueue中得到Message。一般我们要重写Handler的handleMessage(Message msg){}方法来处理,例如以下代码:
public class MainActivity extends Activity {
private TextView textView;
Handler normalHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
Log.i("test",textView.getText().toString());
break;
default:
break;
}
};
};
}
问题:
这个时候Handler会被Android SDK中Lint工具检查警告你(左边那个黄色灯泡+叹号):This Handler class should be static or leaks might occur 。
原因:
This Handler class should be static:
(知识点一)为什么静态内部类能够解决问题呢?或者说静态内部类和非静态内部类的差别是什么?
举例:class A{int a; static int b class B{} static class C{} } (A是外部类,B非静态内部类,C静态内部类,a普通字段。b静态字段)
1)B非静态内部类:
能够訪问A.a和A.b,也就是外部的属性都能方位。
由于B隐式的持有A类对象的引用。相当于A的属性
2)C静态内部类:
C仅仅能够訪问A.b,不能够方位A.a。为什么?由于C不含有A的引用。它和A类是同一个级别。仅仅只是写到了A类的内部。
本例原因:
Handler匿名内部类,隐式的持有了外部类Activity的引用(这就是为什么你能在handleMessage()中调用MainActivity中TextView等的属性)。
--->而以后调
Message message = normalHandler.obtainMessage();
normalHandler.sendMessageAtTime(message , 100*1000);
得到的message中又含有这个Handler的引用(能够看源代码)。
在100秒后message被运行,这期间message被放在MessageQueue中,MessageQueue在Looper中,Looper是线程的本地变量。
也就是说MainActivity即使生命周期走完了也不会垃圾回收,为什么?由于Java的垃圾回收机制,就是看一个对象有没有被引用(从线程中的主要对象開始,对象之间的引用形成网状结构,假设有类的对象不在这张网上,就证明它没被引用。这就是数据结构中图的遍历,什么连通子图,非连通子图)。
而本文中一个MainActivity被Handler持有引用。Handler被Message持有引用,Message被MessageQueue持有引用,MessageQueue被Looper持有引用,Looper为线程本地变量,线程不被摧毁。它就不会被销毁。
所以即便用户已经切换、退出到别的Activity。MainActivity占有的内存仍旧不会被释放。
解决方式:
打破引用链:
1.Message在100秒后被处理。之后回收Message,然后回收MainActivity。
(所以是实际上,你仅仅要不发非常长时间的Message也不会有什么问题)
2.使Handler不持有MainActivity的引用,用弱引用WeakReference:(简单讲,就是仅仅有WeakReference引用的对象。垃圾回收将回收该对象,以后再另写一篇引用的文章吧)
正常代码:
MyHandler handler = new MyHandler(this);
public static class MyHandler extends Handler {
private WeakReference<MainActivity> reference;
public MyHandler(MainActivity activity) {
reference = new WeakReference<MainActivity>(activity);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
Log.i("test",textView.getText().toString());
break;
default:
break;
}
}
}
从Android Handler内部类到WeakReference的知识关联的更多相关文章
- Android内存Context泄露:Handler&内部类
1 public class SampleActivity extends Activity { 2 3 private final Handler mLeakyHandler = new Handl ...
- 【译】什么导致了Context泄露:Handler&内部类
思考下面代码 public class SampleActivity extends Activity { private final Handler mLeakyHandler = new Hand ...
- 【Android】[转] Android Handler应设为static
android开发中,使用Lint检测时会提示这么一句话 : This Handler class should be static or leaks might occur.意为handler应用s ...
- Android Handler leak 分析及解决办法
In Android, Handler classes should be static or leaks might occur, Messages enqueued on the applicat ...
- Android Handler Leak
转自:Android中使用Handler引发的内存泄露 在Activity中,经常会用到自定义的Handler来处理主线程收到的Message,但是ADT20以后,直接定义的如下定义的内部会有提示说这 ...
- Android Handler 机制总结
写 Handler 原理的文章很多,就不重复写了,写不出啥新花样.这篇文章的主要是对 handler 原理的总结. 1.Android消息机制是什么? Android消息机制 主要指 Handler ...
- 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 handler 详解(面试百分之100问到)
handler在Android中被称为“消息处理者”,在多线程中比较常用. handler内部实现原理 handler实现机制:1,Message对象,表示要传递的一个消息,内部使用链表数据结构实现一 ...
- Android handler 可能会造成内存泄露
Android handler 可能会造成内存泄露 Android Studio 使用 Handler 时: private Handler handler = new Handler(){ @Ove ...
随机推荐
- redis安装配置和使用;tomcat安装和使用
virtualbox主要有以下几种方式(不同版本号称法不一样,但实质是一样的): 1.Intelnal Network:利用主机上的全部的虚拟机构建一个虚拟网络 2.NAT:能訪问互联网,不能訪问主机 ...
- 【网络协议】TCP连接的建立和释放
转载请注明出处:http://blog.csdn.net/ns_code/article/details/29382883 TCP首部格式 先看TCP报文段的格式,例如以下; TCP报文段首部的前20 ...
- 虚拟化之docker
1,什么是docker dokcer是应用容器,它是基于系统的虚拟化,他不是基于硬件的虚拟化(KVM),可能这样说有点抽象,我在知乎看到过一个比喻, docker思想是来源于集装箱的,在一艘大船上,可 ...
- 引用System.Runtime.Serialization.Json
vs2012下,重新添加一次System.Runtime.Serialization的引用
- jQuery数组处理函数
写在前面: jQuery的数组处理函数整理如下,如有补充和建议,欢迎评论交流~ 1.$.trim(value) 从value中删除任何前导或尾随的空白字符 2.$.each(containe ...
- 使用Apache JMeter进行SQL优化性能测试
一. 前言 最近在公司里做性能测试,对于一张大概400万数据的表,进行全表扫描往往会比较费时,更不要说有若干这样的表格级联进行检索了.为了能够在不影响生产环境的前提下进行SQL的性能优化,需要首先利用 ...
- (原+转)C++中的lambda表达式
转载请注明出处: http://www.cnblogs.com/darkknightzh/p/5073376.html 参考网址: http://www.cnblogs.com/zhuyp1015/a ...
- SQL Server 2000/2005 分页SQL — 单条SQL语句
有关分页 SQL 的资料很多,有的使用存储过程,有的使用游标.本人不喜欢使用游标,我觉得它耗资.效率低:使用存储过程是个不错的选择,因为存储过程是经过预编译的,执行效率高,也更灵活.先看看单条 SQL ...
- js 事件小结
1,事件对象 e || window.event //ie 2, 取鼠标点击坐标 带有滚动条的 var top = document.documentElement.scrollTop | ...
- javascript写的新闻滚动代码
在企业站中,我们会看到很多新闻列表很平滑的滚动,但是这种功能自己写太浪费时间,下面是我整理好的一组很常用的新闻列表滚动,有上下分页哦! 1.body里面 <div class="tz_ ...