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. 大到可以小说的Y组合子(零)

    问:啊!我想要一个匿名的递归… 答:Y(音同Why)… … … 问:作为一位命令式语言的使用者,为什么会突然折腾起Y组合子呢? 答:的确,这事儿要从很久以前的几次搁浅开始说起…上学的时候,从来没有接触 ...

  2. [Spring入门学习笔记][Spring Boot]

    什么是Spring Boot Spring Boot正是在这样的一个背景下被抽象出来的开发框架,它本身并不提供Spring框架的核心特性以及扩展功能,只是用于快速.敏捷地开发新一代基于Spring框架 ...

  3. 线程:CountDownLatch同步工具

    一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. 类似计数器,当计数器的值为0时,继续往下执行. package ch03; import java.util.R ...

  4. jQuery中click()与trigger方法的区别

    click()可以执行单击事件,但是不可传参. $("button").click(function(){ alert("hello."); }); trigg ...

  5. 使用HttpClient发送GET请求

    HttpRequestMessage http_req_msg = new HttpRequestMessage(); http_req_msg.Method = HttpMethod.Get; ht ...

  6. FULL JOIN 与 CROSS JOIN

    FULL JOIN 只要其中某个表存在匹配,FULL JOIN 关键字就会返回行.(返回JOIN 两端表的所有数据,无论其与另一张表有没有匹配.显示左连接.右连接和内连接的并集) FULL JOIN ...

  7. C#中的委托和游戏中的运用

    C#中的委托与游戏中的运用 1.什么是委托 在C/C++中,有函数指针的概念,即指向函数的指针.当我们调用该指针时,就相当于调用了该指针所指向的函数,这就是函数指针的一个作用,而他另一个作用就是将自己 ...

  8. oracle的nvl和sql server的isnull函数

    最近公司在做Oracle数据库相关产品,在这里作以小结: ISNULL()函数 语法     ISNULL ( check_expression , replacement_value)  参数    ...

  9. automation studio 6.0 破解版 32位

    破解软件在iso文件的patch目录下 链接:http://pan.baidu.com/s/1o8KR7rc 密码:y87g   

  10. appsettings.json

    appsettings.json 目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 在我们之前的Asp.net mvc 开发中,一提到配置文件,我们不由的想到 web.conf ...