Handle机制源码总结
来源:互联网 发布:张信哲没有人知的故事 编辑:程序博客网 时间:2024/05/06 13:54
点击查看原文学习地址
以下是个人总结:
一般我们都是直接Handle handle=new Handle();
但是子线程中直接new Handle会报错,因为Handle的构造方法中的mLooper = Looper.myLooper();这个地方是mLooper是从Looper.myLooper()中获取的。如果我们没用调用Looper. prepare()进行初始化的话,Looper.myLooper()获取到的值就会是空的。而Looper. prepare()是通过sThreadLocal.set(new Looper())的形式新建Looper对象的,ThreadLocal通过获取当前线程将数据存放new Looper()在ThreadLocalMap中;
然后消息队列在Looper的构造方法中被创建。
private Looper(boolean quitAllowed) { mQueue = new MessageQueue(quitAllowed); mThread = Thread.currentThread(); }
然后准备工作完成,当我们用handle发送消息时,不管你怎么send,最终都会走
sendMessageAtTime,或者sendMessageAtFrontOfQueue;这两个的区别就是消息执行的时间不一样而已。而他们都会调用enqueueMessage这个方法执行消息的入队操作。需要注意的是msg.target = this;这一句。在消息上传入了当前的handle,后面在消息分发的时候就直接分发到哪个handle上了。
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); }
最后我们还要调用Looper.loop()事件才会进行会发,来看下loop()的源码:
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; // Make sure the identity of this thread is that of the local process, // and keep track of what that identity token actually is. Binder.clearCallingIdentity(); final long ident = Binder.clearCallingIdentity(); for (;;) { Message msg = queue.next(); // might block if (msg == null) { // No message indicates that the message queue is quitting. return; } // This must be in a local variable, in case a UI event sets the logger final Printer logging = me.mLogging; if (logging != null) { logging.println(">>>>> Dispatching to " + msg.target + " " + msg.callback + ": " + msg.what); } final long traceTag = me.mTraceTag; if (traceTag != 0 && Trace.isTagEnabled(traceTag)) { Trace.traceBegin(traceTag, msg.target.getTraceName(msg)); } try { msg.target.dispatchMessage(msg); } finally { if (traceTag != 0) { Trace.traceEnd(traceTag); } } if (logging != null) { logging.println("<<<<< Finished to " + msg.target + " " + msg.callback); } // Make sure that during the course of dispatching the // identity of the thread wasn't corrupted. final long newIdent = Binder.clearCallingIdentity(); if (ident != newIdent) { Log.wtf(TAG, "Thread identity changed from 0x" + Long.toHexString(ident) + " to 0x" + Long.toHexString(newIdent) + " while dispatching to " + msg.target.getClass().getName() + " " + msg.callback + " what=" + msg.what); } msg.recycleUnchecked(); } }
看重要的代码:
for (;;) { Message msg = queue.next(); // might block ……………… msg.target.dispatchMessage(msg); ………… }
一个死循环,queue.next();链表一直next下去,告诉你可能会Block。
然后就是刚才说的要注意的msg.target,这个我们在上面在将消息入队之前进行了赋值,然后现在就是调用它的dispatchMessage方法,也就是handle的dispatchMessage方法:
public void dispatchMessage(Message msg) { if (msg.callback != null) { handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } }
如果Message没有设置callback则直接调用handleMessage,反之刚执行handleCallback;
- Handle机制源码总结
- Android中Handle机制源码解析
- handle机制
- Android handle机制
- Handle机制详解
- 浅析Android Handle机制
- Android中handle机制
- Handle机制详解
- Handle发送消息机制
- Android消息机制---handle
- Android Handle机制浅析
- Android Handle机制
- handle机制原理
- Handle机制的原理
- Handle通信机制
- Handle机制详解
- Handle机制详解
- Handle机制详解
- JVM类加载1-加载
- 2017春季省赛选拔第一场爆零有感
- Java int string double float之间类型转换
- CSDN-MarkDown-模板
- 关于list一个很有意思的小题
- Handle机制源码总结
- ZOJ3696 Alien's Organ
- Linux入门
- JavaScript对象之面向对象的三种继承方式
- 解决Sublime包管理package control 报错 There are no packages available for installation
- 华容道问题
- android从放弃到坚持放弃第三课(下)
- 【编程实践】狼人杀预选位程序
- Problem--148A--Codeforces--A. Insomnia cure