Android Handler之使用小结
在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之使用小结的更多相关文章
- 十、Android学习第九天——小结(转)
(转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 十.Android学习第九天——小结 通过这段时间的学习,今晚上来做个小小 ...
- Android横竖屏切换小结
Android横竖屏切换小结 (老样子,图片啥的详细文档,可以下载后观看 http://files.cnblogs.com/franksunny/635350788930000000.pdf) And ...
- 深入理解之 Android Handler
深入理解之 Android Handler 一,相关概念 在Android中如果通过用户界面(如button)来来启动线程,然后再线程中的执行代码将状态信息输出到用户界面(如文本框),这时候就会抛 ...
- Android Handler leak 分析及解决办法
In Android, Handler classes should be static or leaks might occur, Messages enqueued on the applicat ...
- Android Handler练习
package com.example.myact12; import java.util.Random; import android.support.v7.app.ActionBarActivit ...
- Android Handler简单使用
package com.example.myhandlertest3; import android.os.Bundle; import android.os.Handler; import andr ...
- Android Handler的使用
大家好我们这一节讲的是Android Handler的使用,在讲Handler之前,我们先提个小问题,就是如何让程序5秒钟更新一下Title. 首先我们看一下习惯了Java编程的人,在不知道Handl ...
- [Android]Handler的消息机制
最经面试中,技术面试中有一个是Handler的消息机制,细细想想,我经常用到的Handler无非是在主线程(或者说Activity)新建一个Handler对象,另外一个Thread是异步加载数据,同时 ...
- 详解Android Handler的使用-别说你不懂handler
我们进行Android开发时,Handler可以说是使用非常频繁的一个概念,它的用处不言而喻.本文就详细介绍Handler的基本概念和用法. Handler的基本概念 Handler主 ...
随机推荐
- B - Maya Calendar(第二季水)
Description During his last sabbatical, professor M. A. Ya made a surprising discovery about the old ...
- win7+IE11 中开发工具报错occurredJSLugin.3005解决办法
系统环境 win7+IE11 报错描述: Exception in window.onload: Error: An error has ocurredJSPlugin.3005 Stack Trac ...
- 模拟Spring依赖注入
通过读取xml文件,利用反射动态加载类和方法,其实就是spring的注入机制模拟,可以清晰的看出整个运行流程 1.配置文件 applicationContext.xml <beans> & ...
- push() & concat()
eg. var arr = []; arr.push(1); arr.push([2, 3]); arr.push(4, 5); arr = arr.concat(6); arr = arr.conc ...
- c#接口定义与应用
public interface IBankAccount //只能加public修饰符,或者什么都不加 { void Playin(decimal money); //函数前不加任何修饰符号 boo ...
- ecshop物料库存管理
1.创建物流库存表.sql语句: CREATE TABLE IF NOT EXISTS `emws_materials` (`id` mediumint(8) unsigned NOT NULL au ...
- racle undo 解析
racle undo 解析 声明一下:关于oracle的文章基于boobooke小布老师视频,在我学习的过程中,每有体会拿来分享,虽然从理解到整理分享很耗时,但我想这样的学习是扎实的. Undo是干嘛 ...
- hightchart or hightstock 格式Y数据
hightchart or hightstock 格式Y数据,鼠标放在上面显示两位小数 方法一: tooltip: { shared: true, crosshairs: true , formatt ...
- listview加载网络图片
ListView加载网络数据和图片 2013-09-25 00:08:10| 分类: 默认分类 | 标签:android |举报|字号 订阅 如,从服务器端获得商品名称.价格.简介和图片 ...
- 区间dp-hdu-4745-Two Rabbits
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4745 题目意思: 给n个环状的数,A.B两人沿相反的方向走,每单位时间走一步,要求相同时间两人到达相 ...