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的知识关联的更多相关文章

  1. Android内存Context泄露:Handler&内部类

    1 public class SampleActivity extends Activity { 2 3 private final Handler mLeakyHandler = new Handl ...

  2. 【译】什么导致了Context泄露:Handler&内部类

    思考下面代码 public class SampleActivity extends Activity { private final Handler mLeakyHandler = new Hand ...

  3. 【Android】[转] Android Handler应设为static

    android开发中,使用Lint检测时会提示这么一句话 : This Handler class should be static or leaks might occur.意为handler应用s ...

  4. Android Handler leak 分析及解决办法

    In Android, Handler classes should be static or leaks might occur, Messages enqueued on the applicat ...

  5. Android Handler Leak

    转自:Android中使用Handler引发的内存泄露 在Activity中,经常会用到自定义的Handler来处理主线程收到的Message,但是ADT20以后,直接定义的如下定义的内部会有提示说这 ...

  6. Android Handler 机制总结

    写 Handler 原理的文章很多,就不重复写了,写不出啥新花样.这篇文章的主要是对 handler 原理的总结. 1.Android消息机制是什么? Android消息机制 主要指 Handler ...

  7. 85、android handler的警告Handler Class Should be Static or Leaks Occur

    转载:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1106/1922.html 在使用Handler更新UI的时候,我是这样写 ...

  8. Android handler 详解(面试百分之100问到)

    handler在Android中被称为“消息处理者”,在多线程中比较常用. handler内部实现原理 handler实现机制:1,Message对象,表示要传递的一个消息,内部使用链表数据结构实现一 ...

  9. Android handler 可能会造成内存泄露

    Android handler 可能会造成内存泄露 Android Studio 使用 Handler 时: private Handler handler = new Handler(){ @Ove ...

随机推荐

  1. UVa 10256 The Great Divide,推断两个凸包是否相离

    先从给出的两个点集中分别计算出两个凸包, 然后推断两个凸包是否相离. #include<cstdio> #include<vector> #include<cmath&g ...

  2. HDU 1827 Summer Holiday(Tarjan缩点)

    Problem Description To see a World in a Grain of Sand  And a Heaven in a Wild Flower,  Hold Infinity ...

  3. [CSAPP笔记][第一章计算机系统漫游]

    计算机系统漫游 我们通过追踪hello程序的生命周期来开始对系统的学习—–从它被程序员创建,到系统上运行,输出简单的消息,然后终止.我们沿着这个程序的生命周期,简要介绍一些逐步出现的概念,专业术语和组 ...

  4. 【问题备注】VS2012不能输入代码,文字…

    第一次遇到,非常奇怪,一个项目,VS2012能正常打开,但是不能输入代码. 对比分析发现,其他项目能正常work.在于一个问题就是,VS2012 右下角有个INS一直在转一直analyzing,而正常 ...

  5. JAVA加密

    [源地址http://www.iteye.com/topic/1122076/] 加密,是以某种特殊的算法改变原有的信息数据,使得未授权的用户即使获得了已加密的信息,但因不知解密的方法,仍然无法了解信 ...

  6. iOS 判断设备是否越狱

    我们在开发过程中,需要知道设备是否越狱,在网上查看很多资料,为此封装一些判断的方法. 上代码,不解释: .h文件 #import <Foundation/Foundation.h> @in ...

  7. jquery动态删除、复制、包裹DOM节点

    1.remove()方法 移除满足条件的元素 <html> <head> <meta http-equiv="Content-Type" conten ...

  8. (转)ubuntu下如何查看软件安装目录以及安装版本

    1.查询版本 aptitude show 软件名 例如:aptitude show kde-runtime 显示如下: ****@ubuntu:~$ aptitude show kde-runtime ...

  9. 一个有趣的问题——MySQL中varchar的最大长度

    明明维护了一个1k的最小堆,可是输出到MySQL里却只有九百多行数据. 查log,发现这么一段内容: stderr logs com.mysql.jdbc.MysqlDataTruncation: D ...

  10. bootstrap模态框垂直居中

    很久没有写东西了,之前想写一些移动端的东西以后补上吧,移动端发展还是蛮快的,回正题. 因为最近在弄一个系统,系统中引用了bootstrap,发现模态框垂直不居中,遂搜索了一下,也都试了一下,无非都是在 ...