Handler机制
来源:互联网 发布:英雄联盟 kda 软件 编辑:程序博客网 时间:2024/06/05 07:35
一、handler中用到的一些类。
1. Message
消息,理解为线程间通讯的数据单元。例如后台线程在处理数据完毕后需要更新UI,则可发送一条包含更新信息的Message给UI线程。
2. Message Queue
消息队列,用来存放通过Handler发布的消息,按照先进先出执行。
3. Handler
Handler是Message的主要处理者,负责将Message添加到消息队列以及对消息队列中的Message进行处理。
4. Looper
循环器,扮演Message Queue和Handler之间桥梁的角色,循环取出Message Queue里面的Message,并交付给相应的Handler进行处理。
5. 线程
UI thread 通常就是main thread,而Android启动程序时会替它建立一个Message Queue。
每一个线程里可含有一个Looper对象以及一个MessageQueue数据结构。在你的应用程序里,可以定义Handler的子类别来接收Looper所送出的消息。
二、Handler的用法:
1:传递message。用于接收子线程发送的数据,并用配合主线程更新UI。它有如下方法:
sendEmptyMessage(int what);//发送一个空的消息
sendMessage(Message msg);//发送msg
sendMessageAtTime(Message msg,long uptimeMillis);//在指定时间发送msg
sendMessageDelayed(Message msg,long delayMills);//延迟delatMills秒后发送msg
以上方法最终的调用 其实调用sendMessageAtTime这个方法
2.传递RUnnable对象。通过Handler绑定消息队列,主要有以下方法:
post(Runnable r);
postAtTime(Runnable r,long uptimeMillis);
postDelated(Runnable r,long delayMills);
post一类的方法,允许你排列一个Runnable对象到主线程队列中。所以直接在其run方法中更新UI也是没问题的,因为它处于主线程的队列中。
以上方法其实最终还是调用了 1中的sendMessageAtTime方法;
关于sendMessageAtTime方法,它的源码如下:
public boolean sendMessageAtTime(Message msg, long uptimeMillis) { MessageQueue queue = mQueue; if (queue == null) { RuntimeException e = new RuntimeException( this + " sendMessageAtTime() called with no mQueue"); Log.w("Looper", e.getMessage(), e); return false; } return enqueueMessage(queue, msg, uptimeMillis);}
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) { msg.target = this; if (mAsynchronous) { msg.setAsynchronous(true); } return queue.enqueueMessage(msg, uptimeMillis);}queue.enqueueMessage方法的主要操作其实就是向MessageQueue中插入一条数据(注意:MessageQueue虽然翻译过来是消息队列,但是它的内部存储结构并不是真正的队列,而是采用单链表的数据结构来存储消息列表)也就是说Handler发送消息的过程仅仅是向MessageQueue中插入了一条消息,MessageQueue的next方法就会返回这条消息给Looper,Looper收到消息后就开始处理了,最终消息由Looper交由Handler处理,即Handler的dispatchMessage方法会被调用。
3.传递Callback对象。
三、Handler原理
Handler封装了消息的发送(主要包括消息发送给谁)
Looper:
(a).内部包含了一个消息队列MessageQueue,所有Handler发送的消息都走向这个队列。
(b).Looper.loop()方法会一直从MessageQueue取消息,如果有就会通知对应的Handler,调用dispatchMessage(Message msg)方法;而dispatchMessage方法又会调用handlerMessage方法,从而通知handler消息来了。
下面是部分源码:
public static void loop() { final Looper me = myLooper(); if (me == null) { throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); } final MessageQueue queue = me.mQueue;... for (;;) { Message msg = queue.next(); // might block if (msg == null) { // No message indicates that the message queue is quitting. return; }... try { msg.target.dispatchMessage(msg); } finally { if (traceTag != 0) { Trace.traceEnd(traceTag); } }... }}
public void dispatchMessage(Message msg) { if (msg.callback != null) { handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); }}从源码中也可以看到,loop方法会先通过myLooper方法获取prepare()方法中存放进去的Looper对象,并且得到当前looper下的消息队列。然后一直调用queue.next方法获取消息,当有消息后通过dispatchMessage方法回调hendleMessage方法通知当前handler。
- Handler机制
- Handler机制
- handler机制
- handler机制
- Handler机制
- Handler机制
- handler机制
- Handler机制
- handler机制
- Handler机制
- handler机制
- Handler机制
- Handler机制
- Handler机制
- handler机制
- handler机制
- Handler机制
- Handler机制
- 压缩图片的方式个人总结
- isight调用matlab专业模块
- MySql获取时间范围中的随机日期
- Struts(6)Struts框架中使用filter过滤关键词
- Swift3 QQ联系人列表
- Handler机制
- 数据访问层
- Tablayout Viewpager的实现
- ubuntu下编译linux内核
- 事件分发机制机制详解
- HDOJ1003(最大连续子串)
- UVA
- Android xml编写tween animation(补间动画)
- 557. Reverse Words in a String III