从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 ...
随机推荐
- 大到可以小说的Y组合子(零)
问:啊!我想要一个匿名的递归… 答:Y(音同Why)… … … 问:作为一位命令式语言的使用者,为什么会突然折腾起Y组合子呢? 答:的确,这事儿要从很久以前的几次搁浅开始说起…上学的时候,从来没有接触 ...
- [Spring入门学习笔记][Spring Boot]
什么是Spring Boot Spring Boot正是在这样的一个背景下被抽象出来的开发框架,它本身并不提供Spring框架的核心特性以及扩展功能,只是用于快速.敏捷地开发新一代基于Spring框架 ...
- 线程:CountDownLatch同步工具
一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. 类似计数器,当计数器的值为0时,继续往下执行. package ch03; import java.util.R ...
- jQuery中click()与trigger方法的区别
click()可以执行单击事件,但是不可传参. $("button").click(function(){ alert("hello."); }); trigg ...
- 使用HttpClient发送GET请求
HttpRequestMessage http_req_msg = new HttpRequestMessage(); http_req_msg.Method = HttpMethod.Get; ht ...
- FULL JOIN 与 CROSS JOIN
FULL JOIN 只要其中某个表存在匹配,FULL JOIN 关键字就会返回行.(返回JOIN 两端表的所有数据,无论其与另一张表有没有匹配.显示左连接.右连接和内连接的并集) FULL JOIN ...
- C#中的委托和游戏中的运用
C#中的委托与游戏中的运用 1.什么是委托 在C/C++中,有函数指针的概念,即指向函数的指针.当我们调用该指针时,就相当于调用了该指针所指向的函数,这就是函数指针的一个作用,而他另一个作用就是将自己 ...
- oracle的nvl和sql server的isnull函数
最近公司在做Oracle数据库相关产品,在这里作以小结: ISNULL()函数 语法 ISNULL ( check_expression , replacement_value) 参数 ...
- automation studio 6.0 破解版 32位
破解软件在iso文件的patch目录下 链接:http://pan.baidu.com/s/1o8KR7rc 密码:y87g
- appsettings.json
appsettings.json 目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 在我们之前的Asp.net mvc 开发中,一提到配置文件,我们不由的想到 web.conf ...