从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 ...
随机推荐
- poj1703--Find them, Catch them(并查集应用)
Find them, Catch them Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 32073 Accepted: ...
- hadoop备战:一台x86计算机搭建hadoop的全分布式集群
主要的软硬件配置: x86台式机,window7 64位系统 vb虚拟机(x86的台式机至少是4G内存,才干开3台虚机) centos6.4操作系统 hadoop-1.1.2.tar.gz jdk- ...
- 【算法】插入排序 insertion_sort
准备写个<STL 源代码剖析>的读书笔记,开个专栏.名为<STL 的实现>,将源代码整理一遍.非常喜欢侯捷先生写在封底的八个字:天下大事.必作于细.他在书中写到:"我 ...
- cocoapods在OS X Yosemite系统中报错
之前使用cocoapods一直是正常使用的,刚换了电脑,使用pod install的时候报错: /System/Library/Frameworks/Ruby.framework/Versions/2 ...
- Global.asax使用2
ASP.NET中利用Application和Session统计在线人数.历史访问量 先来简单说一下ASP.NET中的Application和Session 下图是我们非常熟悉的Web应用程序的结构: ...
- 如何在asp.net中如何在线播放各类视频文件
一.后台拼字符串动态加载写法 前台调用代码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" &q ...
- SQL Server 模式和名称解析
模式实际上是名称空间,因此在SQL Serve中调用数据库对象时,一定要设置对象引用的环境.每个用户都被赋予了一个默认模式,在用户登录SQL Server并凋用数据库对象时,这个默认模式就是对象引用方 ...
- libxml两种换行方法
好久没上来留下一些记录了,可能是太忙,又或者是过于慵懒便疏于整理. libxml是一个开源的库,linux下解析xml文件经常用到,进行一些创读增删的操作. 最开始接触的时候,看到了一个简明易懂的&l ...
- Could not load file or assembly 'Oracle.DataAccess' or one of its dependencies. An attempt was made to load a program with an incorrect format.
I have installed a Web application on IIS 7.0 windows server 2008 R2 64 bit OS I am refering a oracl ...
- shell脚本例子
#!/bin/sh str="####" echo $1 | grep $str 1>/dev/null if [ `echo $?` -eq 0 ] then ec ...