在android开发中,使用Handler处理各种消息机制。

Handler用于处理和从队列MessageQueue中得到Message。一般我们要重写Handler的handleMessage(Message msg){}方法来处理,如下代码:

使用内部类的方式实现,官方是不建议这样写的。

public class MainActivity extends Activity {

	Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
//处理各种接受消息逻辑
break; default:
break;
}
};
};
}

  

这个时候Handler会被Android SDK中Lint工具检查警告你(左边那个黄色灯泡+叹号):This Handler class should be static or leaks might occur 。

为什么静态内部类可以解决这个问题呢?或者说静态内部类和非静态内部类的区别是什么?

举例: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类的内部。

link的警告原因:

Handler匿名内部类,隐式的持有了外部类Activity的引用。

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:
//处理接受消息逻辑
break; default:
break;
}
}
}

  

为何Android界面更新,Handler作为匿名内部类来实现handlerMessage方法

最重要的不是线程安全问题,而是android组件的监听方法中只能访问final 的属性,所以是无法修改的,只能把它交给handler处理。不能在非UI线程,绘制渲染洁面。

为何需要Handler而不用Thread。除了消息模型是UI框架的经典模式外,还涉及到UI组件不允许跨线程访问的限制。无论是.NET也好,swing也好,android也好,不允许在非UI线程中操作这一点都一样。
Handler便是android框架中异步线程代码到达同步线程的官方通道。从另一个角度说,这种基于消息模型的通信模式有时也很有用。相关的例子有IntentService,HandlerThread等。

转自:http://www.bkjia.com/Androidjc/904357.html

Android Handler之使用小结的更多相关文章

  1. 十、Android学习第九天——小结(转)

    (转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 十.Android学习第九天——小结 通过这段时间的学习,今晚上来做个小小 ...

  2. Android横竖屏切换小结

    Android横竖屏切换小结 (老样子,图片啥的详细文档,可以下载后观看 http://files.cnblogs.com/franksunny/635350788930000000.pdf) And ...

  3. 深入理解之 Android Handler

    深入理解之 Android Handler   一,相关概念 在Android中如果通过用户界面(如button)来来启动线程,然后再线程中的执行代码将状态信息输出到用户界面(如文本框),这时候就会抛 ...

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

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

  5. Android Handler练习

    package com.example.myact12; import java.util.Random; import android.support.v7.app.ActionBarActivit ...

  6. Android Handler简单使用

    package com.example.myhandlertest3; import android.os.Bundle; import android.os.Handler; import andr ...

  7. Android Handler的使用

    大家好我们这一节讲的是Android Handler的使用,在讲Handler之前,我们先提个小问题,就是如何让程序5秒钟更新一下Title. 首先我们看一下习惯了Java编程的人,在不知道Handl ...

  8. [Android]Handler的消息机制

    最经面试中,技术面试中有一个是Handler的消息机制,细细想想,我经常用到的Handler无非是在主线程(或者说Activity)新建一个Handler对象,另外一个Thread是异步加载数据,同时 ...

  9. 详解Android Handler的使用-别说你不懂handler

    我们进行Android开发时,Handler可以说是使用非常频繁的一个概念,它的用处不言而喻.本文就详细介绍Handler的基本概念和用法. Handler的基本概念         Handler主 ...

随机推荐

  1. Reverse Words in a String (JAVA)

    Given an input string, reverse the string word by word. For example,Given s = "the sky is blue& ...

  2. Citrix 服务器虚拟化之十一 Xenserver管理vApps

    Citrix 服务器虚拟化之十一  Xenserver管理vApps vApps是把几个业务相关的虚拟机作为一个单一实体管理,把vApps中的虚拟机的称为Application.启动vApps时其中包 ...

  3. Java三大特征之继承(二)

    在<Think in java>中有这样一句话:复用代码是Java众多引人注目的功能之一.但要想成为极具革命性的语言,仅仅能够复制代码并对加以改变是不够的,它还必须能够做更多的事情.在这句 ...

  4. atoi atol strtod strtol strtoul _gcvt

    如果以下函数,您在使用的时候,总是输出一个莫名的值,是因为您忘记了引用头文件 #include <stdlib.h> 1- atoi int atoi(const char *nptr); ...

  5. 分析BGARefreshLayout-master

    一.知识点,创建BaseActivity 建立方法的逻辑顺序 并将一些常用的方法填充到其中 ①.将initView().setListener().onClick().processLogic()方法 ...

  6. flask 后台表单验证模块

    我不想直接用flask的wtf模块,太大,功能太多,用不了.但后台也不能不做验证吧,我比较懒,不想一行一行写代码验证,所以就写了一个验证模块,对于小项目也够用了 # encoding=utf-8 # ...

  7. QT:使用“状态模式”绘制界面

    QT与很多GUI库不同(如MFC),它不能随时随地地在界面上画图,只能在界面类的painterEvent中画图,如此一来,想在绘制QT界面时使用状态模式(GOF的23种设计模式之一)就有点困难了,作为 ...

  8. 非自定义和自定义Dialog的介绍!!!

    一.非自定义Dialog的几种形式介绍 转自:http://www.kwstu.com/ArticleView/kwstu_20139682354515 前言 对话框对于应用也是必不可少的一个组件,在 ...

  9. CSS 定位 (Positioning)学习

    最近被css的定位要搞疯了...下面我总结一下最近学习东西. 先介绍几个概念: 块框:div.h1 或 p 元素常常被称为块级元素.这意味着这些元素显示为一块内容,即“块框”. 行内框:与之相反,sp ...

  10. Bag of Words(BOW)模型

    原文来自:http://www.yuanyong.org/blog/cv/bow-mode 重复造轮子并不是完全没有意义的. 这几天忙里偷闲看了一些关于BOW模型的知识,虽然自己做图像检索到目前为止并 ...