Android handler机制
2016-01-27 16:03
393 查看
Handler机制是线程间通信的实现;
Handler类持有MessageQueue 引用,Looper引用。主要是用来处理Message的发送,入列和出列;
持有Looper引用的目的是获取MessageQueue引用,Looper通过ThreadLocal才属于它的线程(主线程或子线程),由于主线程之前就持有自己的Looper对象,所以实例化Handler的时候不用调用Looper.prepare()方法进行Looper的设定,直接在主线程中实例化Handler对象就可以发送消息;
Looper类持有一个MessageQueue引用,用来对queue中的Message进行循环处理;
如果Handler是在子线程中实例化的,那么它持有的Looper就是属于该子线程的,在子线程中进行消息的循环需要先设定Looper:
Handler在哪个线程中实例化,那么它就处理该线程中的消息;可是如果多个线程同时通过这个handler发送消息呢,由于Looper是线程隔离的,但是messageQueue却要暴露给其他的线程,这样才能允许其他的线程发送入列消息,所以MessagQueue入列时需要同步化:
Message类持有一个链表,它会缓存用过的Messages,loop循环就是不断的从链表头中取出消息,如果取出的是null则中断loop:
Handler类持有MessageQueue 引用,Looper引用。主要是用来处理Message的发送,入列和出列;
持有Looper引用的目的是获取MessageQueue引用,Looper通过ThreadLocal才属于它的线程(主线程或子线程),由于主线程之前就持有自己的Looper对象,所以实例化Handler的时候不用调用Looper.prepare()方法进行Looper的设定,直接在主线程中实例化Handler对象就可以发送消息;
Looper类持有一个MessageQueue引用,用来对queue中的Message进行循环处理;
如果Handler是在子线程中实例化的,那么它持有的Looper就是属于该子线程的,在子线程中进行消息的循环需要先设定Looper:
public void run(){ Looper.prepare();//会实例化一个looper对象,并属于当前线程 handler = new Handler(){ public void handleMessage(Message msg){} } Looper.loop();//获取当前线程的looper进行循环 }
Handler在哪个线程中实例化,那么它就处理该线程中的消息;可是如果多个线程同时通过这个handler发送消息呢,由于Looper是线程隔离的,但是messageQueue却要暴露给其他的线程,这样才能允许其他的线程发送入列消息,所以MessagQueue入列时需要同步化:
boolean enqueueMessage(Message msg, long when) { if (msg.target == null) { throw new IllegalArgumentException("Message must have a target."); } if (msg.isInUse()) { throw new IllegalStateException(msg + " This message is already in use."); } synchronized(this) { if (mQuitting) { IllegalStateException e = new IllegalStateException( msg.target + " sending message to a Handler on a dead thread"); Log.w(TAG, e.getMessage(), e); msg.recycle(); return false; } <span style="white-space:pre"> </span> msg.markInUse(); msg.when = when; Message p = mMessages; boolean needWake;
<span style="white-space:pre"> </span> //如果链表没有节点,或时间为0,或小于头节点,则 if (p == null || when == 0 || when < p.when) { // New head, wake up the event queue if blocked. msg.next = p; mMessages = msg; needWake = mBlocked; } else { // Inserted within the middle of the queue. Usually we don't have to wake // up the event queue unless there is a barrier at the head of the queue // and the message is the earliest asynchronous message in the queue. needWake = mBlocked && p.target == null && msg.isAsynchronous(); Message prev; for (;;) { prev = p; p = p.next;
<span style="white-space:pre"> </span> //如果到了链表的最后或时间小于某一节点,则插入到该节点之前 if (p == null || when < p.when) { break; } if (needWake && p.isAsynchronous()) { needWake = false; } } msg.next = p; // invariant: p == prev.next prev.next = msg; } // We can assume mPtr != 0 because mQuitting is false. if (needWake) { nativeWake(mPtr); } } return true; }
Message类持有一个链表,它会缓存用过的Messages,loop循环就是不断的从链表头中取出消息,如果取出的是null则中断loop:
Message next() { // Return here if the message loop has already quit and been disposed. // This can happen if the application tries to restart a looper after quit // which is not supported. final long ptr = mPtr; if (ptr == 0) { return null; } int pendingIdleHandlerCount = -1; // -1 only during first iteration int nextPollTimeoutMillis = 0; for (;;) { if (nextPollTimeoutMillis != 0) { Binder.flushPendingCommands(); } nativePollOnce(ptr, nextPollTimeoutMillis); synchronized (this) { // Try to retrieve the next message. Return if found. final long now = SystemClock.uptimeMillis(); Message prevMsg = null; Message msg = mMessages; if (msg != null && msg.target == null) { // Stalled by a barrier. Find the next asynchronous message in the queue. do { prevMsg = msg; msg = msg.next; } while (msg != null && !msg.isAsynchronous()); } if (msg != null) { if (now < msg.when) { // Next message is not ready. Set a timeout to wake up when it is ready. nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE); } else { // Got a message. mBlocked = false; if (prevMsg != null) { prevMsg.next = msg.next; } else { mMessages = msg.next; } msg.next = null; if (DEBUG) Log.v(TAG, "Returning message: " + msg); msg.markInUse(); return msg; } } else { // No more messages. nextPollTimeoutMillis = -1; }
<span style="white-space:pre"> </span>// Process the quit message now that all pending messages have been handled. if (mQuitting) { dispose(); return null; }
相关文章推荐
- Android Audio System之三:AudioPolicyService和AudioPolicyManager
- 属性动画的简单使用和总结
- Android Gradle介绍
- Android OpenCv进行图片比对
- Android Audio System之二:AudioFlinger
- Android Studio项目目录结构介绍
- Android之服务(五)IntentService的使用
- Android Audio System之一:AudioTrack如何与AudioFlinger交换音频数据
- 自定义ListView(加载数据长度的高度)
- android studio ndk 调试
- Android之服务(四)前台服务
- Android 检查运行慢原因和分析
- 史上最详细的Android Studio系列教程二--基本设置与运行
- Android Design Support Library控件使用总结(二)
- Android之服务(三)服务的生命周期
- android中的MD5、Base64、DES/3DES/ADES加解密
- 将Github下载的项目导入android studio
- Android之服务(二)活动和服务进行通信
- Android注解式开发BufferKnife的使用
- android 验证码 (canvas)