在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. B - Maya Calendar(第二季水)

    Description During his last sabbatical, professor M. A. Ya made a surprising discovery about the old ...

  2. win7+IE11 中开发工具报错occurredJSLugin.3005解决办法

    系统环境 win7+IE11 报错描述: Exception in window.onload: Error: An error has ocurredJSPlugin.3005 Stack Trac ...

  3. 模拟Spring依赖注入

    通过读取xml文件,利用反射动态加载类和方法,其实就是spring的注入机制模拟,可以清晰的看出整个运行流程 1.配置文件 applicationContext.xml <beans> & ...

  4. push() & concat()

    eg. var arr = []; arr.push(1); arr.push([2, 3]); arr.push(4, 5); arr = arr.concat(6); arr = arr.conc ...

  5. c#接口定义与应用

    public interface IBankAccount //只能加public修饰符,或者什么都不加 { void Playin(decimal money); //函数前不加任何修饰符号 boo ...

  6. ecshop物料库存管理

    1.创建物流库存表.sql语句: CREATE TABLE IF NOT EXISTS `emws_materials` (`id` mediumint(8) unsigned NOT NULL au ...

  7. racle undo 解析

    racle undo 解析 声明一下:关于oracle的文章基于boobooke小布老师视频,在我学习的过程中,每有体会拿来分享,虽然从理解到整理分享很耗时,但我想这样的学习是扎实的. Undo是干嘛 ...

  8. hightchart or hightstock 格式Y数据

    hightchart or hightstock 格式Y数据,鼠标放在上面显示两位小数 方法一: tooltip: { shared: true, crosshairs: true , formatt ...

  9. listview加载网络图片

    ListView加载网络数据和图片 2013-09-25 00:08:10|  分类: 默认分类 |  标签:android  |举报|字号 订阅     如,从服务器端获得商品名称.价格.简介和图片 ...

  10. 区间dp-hdu-4745-Two Rabbits

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4745 题目意思: 给n个环状的数,A.B两人沿相反的方向走,每单位时间走一步,要求相同时间两人到达相 ...