Android学习自记 之 Handler
来源:互联网 发布:临沂盛誉seo 编辑:程序博客网 时间:2024/06/05 20:46
- Handler、Looper、MessageQueue 和 Thread 这三个class紧密相关的:默认情况下,一个新创建的Thread对象是没有循环消息队列可用的,当在该线程中创建了Looper对象(可直接调用静态方法 Looper.prepare() 来实现创建)后,该Looper对象默认会有一个MessageQueue对象与之绑定,从而该线程也就拥有了一个MessageQueue。
- 在Thread对象中,除了创建Looper之外,还需要调用 Looper.loop() 这个静态方法才能启动该线程的消息队列。为了简化此工作,android系统提供了 HandlerThread 这个Thread的子类,可直接创建一个具有已激活消息队列的线程,该线程默认的run( ) 方法只做一件事情,即处理来自该线程MessageQueue的Message和Runnable对象。
- 当一个线程具有了消息队列之后,就可以创建一个Handler对象与该线程及该线程的消息队列绑定。Handler最基本的创建方式有两种:
1. new Handler() ——这种方式下,Handler对象与当前线程及其消息队列绑定
2. new Handler(Looper looper) ——这种方式下Handler对象与该Looper对象所在的线程及其消息队列绑定
( PS:一个HandlerThread线程是可以通过 getLooper() 得到其关联的Looper对象) - 一个线程的消息队列实际可以看作包含两个queue结构,一个queue存放Message对象,另外一个queue存放Runnable对象。当一个Handler对象与某线程绑定之后就可以通过该Handler对象向线程的消息队列中添加Message或Runnable对象了
- Handler对象向线程的消息队列中添加Runnable对象是通过Handler对象的post系列方法来实现的,最常用的包括 post(Runnable r),postAtTime(Runnable r, long uptimeMillis) 和 postDelayed(Runnable r, long delayMillis) 通过这些方法可以实现Runnable对象的 run( ) 方法在该线程中的定时执行。
个人谨记:
1. 无论采用哪种post方法,Runnable被Handler加入到线程消息队列的动作是立即完成的,带有时间参数的postDelayed或者postAtTime方法指定的是Runnable的run()方法在线程中被调用的时间,而不是Runnable对象加入消息队列的时间。
2. post系列方法加入到消息队列中的Runnable对象并不是按照调用post的顺序被执行的,即如下的代码段
handler.postDelayed(r1, 5000);
handler.postDelayed(r2, 1000);
handler.post(r3);
执行的顺序是 r3.run(),r2.run(), r1.run()。??这似乎与queue“先进先出”的原则不符合,个人只能在此暂时理解为使用postDelayed()方法的Runnable对象在Runnable Queue中被置后了。 - Message包含 int arg1, int arg2, int what, Object object 这几个成员变量, 可用作Message中简单信息的高效传递。比较复杂的数据则可以通过Message中的 setData(Bundle data) 来实现,Bundle 其实就是 key 为String类型,value类型众多的Map类。
一个空 Message 对象是通过 Handler 对象的 obtainMessage() 方法从特定线程的Looper创建的message pool中获得的,也就是说一个Message在创建之初就已经与一个Handler、一个线程绑定关联的。Message内容被确定后添加到线程的消息队列有两种方式:
1. 通过与Message相关的Handler对象的send系列方法来实现的,最常用的包括 sendEmptyMessage(int what),
sendEmptyMessage(int what), sendEmptyMessage(int what),
sendEmptyMessageDelayed(int what, long delayMillis),
sendMessage(Message msg) 和 sendMessageDelayed(Message msg, long delayMillis)
2. 直接调用Message对象的 sendToTarget() 方法。
个人谨记:
Message与Runnable进入消息队列的方式不同。之前提到过无论采用哪种post方法,Runnable进入线程消息队列的动作都是立即完成的,postDelayed()方法delay的只是他们的run()方法被线程执行的时间;
而Message就不同了,sendMessageDelayed() 方法延迟的直接是Message排入消息队列的时间。MessageQueue严格的遵循“先进先出”的原则。 - Handler对象通过其 public void handleMessage(Message msg) 方法不停地在其绑定线程中处理线程消息队列(准确的说是Message Queue)中的Message
- Handler将 Message 或 Runnable 放入线程的消息队列这个动作,与线程处理这些Message或执行Runnable的run()方法的动作—— 是异步的,即在当前线程中执行Handler将Message或Runnable放入消息队列的语句之后,当前线程就顺序执行下去,执行过程不会受到消息处理的影响。
- 实际上,在android文档中可以看到每一个所有的View都运行和被操作在UI线程中,而UI线程有一个UI Events Queue。因此UI主线程处理用户的交互操作等events,同样是将这些events看作是放入消息队列的Message,如果Handler就是与UI主线程绑定的,那么Handler放入消息队列的 Message 或 Runnable 的处理就和用户交互events处理按照一定的调度算法互相竞争CPU,可能会导致UI主线程响应用户感观变差。
如果将Handler与UI线程之外的其他线程绑定,则Handler对象添加的Message或Runnable的处理都在另外的线程中,就不会影响UI线程了
- Android学习自记 之 Handler
- Android 之 handler 学习
- Android之Handler学习
- Android学习之handler
- Android之Handler学习
- android之handler学习
- 记android学习之路----Handler机制
- Android学习之Handler学习
- android学习笔记之Handler
- android多线程学习之handler
- Android学习笔记之Handler
- Android学习笔记之Handler(一)
- Android学习之问题处理程序Handler
- Android学习之Handler的使用
- Android学习之Handler的使用
- android学习笔记之handler(1)
- android学习笔记之handler(2)
- android学习笔记之handler初接触!
- Linux逻辑卷管理LVM2详解
- Linux 创建文件系统及挂载文件系统流程详解
- 关于Oracle数据库中行迁移/行链接的问题
- 通过路径获取媒体文件信息
- .net remoting
- Android学习自记 之 Handler
- Oracle开发人员应该具备的几个资源
- DbUtil 及编码心得2
- USING INDUCTION TO DESIGN 使用归纳法设计算法 [1/14]
- TQ2440系列二 存储器地址分配
- 使用 load data 将格式化文件导入mysql表
- Android
- Oracle———单行函数
- Android 使用gdb调试