这篇其实是体外的,对于想了解人,可以研究下,或者说助于理解handler吧。。。
先说下handler的三个构造函数开始我们的源码解析之旅吧。。。
(一)默认的构造函数
/**
* Default constructor associates this handler with the queue for the
* current thread.
*
* If there isn't one, this handler won't be able to receive messages.
*/
public Handler() {
if (FIND_POTENTIAL_LEAKS) {
final Class<? extends Handler> klass = getClass();
if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
(klass.getModifiers() & Modifier.STATIC) == 0) {
Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
klass.getCanonicalName());
}
}
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = null;
}
其中, MessageQueue mQueue存放消息的消息队列,Looper mLooper消息循环,Callback mCallback回调;
看下代码 mLooper = Looper.myLooper();
这里我们看下Looper的源码:
/**
* Return the Looper object associated with the current thread. Returns
* null if the calling thread is not associated with a Looper.
*/
public static Looper myLooper() {
return sThreadLocal.get();
}
/** Initialize the current thread as a looper.
* This gives you a chance to create handlers that then reference
* this looper, before actually starting the loop. Be sure to call
* {@link #loop()} after calling this method, and end it by calling
* {@link #quit()}.
*/
public static void prepare() {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper());
}
而这里的 static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
发现在myLooper() 中得到的函数在prepare函数加入了消息循环的sThreadLocal.set(new Looper());
这里很好的说明了,我们在使用mylooper()的时候,需要先调用prepare()方法。
2. CallBack回调函数
/**
* Constructor associates this handler with the queue for the
* current thread and takes a callback interface in which you can handle
* messages.
*/
public Handler(Callback callback) {
if (FIND_POTENTIAL_LEAKS) {
final Class<? extends Handler> klass = getClass();
if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
(klass.getModifiers() & Modifier.STATIC) == 0) {
Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
klass.getCanonicalName());
}
}
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = callback;
}
这个构造函数与默认构造函数唯一不同的就是mCallback区别,那我们就分析CallBack这个接口吧!
/**
* Callback interface you can use when instantiating a Handler to avoid
* having to implement your own subclass of Handler.
*/
public interface Callback {
public boolean handleMessage(Message msg);
}
这个其实就是在消息派发的时候,区分是在哪里处理消息的,如果Callback不为空,则消息就在他实现的这个借口的handleMessage()方法里处理。
3. 传入消息循环Looper
/**
* Use the provided queue instead of the default one.
*/
public Handler(Looper looper) {
mLooper = looper;
mQueue = looper.mQueue;
mCallback = null;
}
这个是传入消息循环,而不是系统默认生成,而是我们自己创建或者从已有的消息循环拿过来使用
4.消息循环和CallBack回调函数
/**
* Use the provided queue instead of the default one and take a callback
* interface in which to handle messages.
*/
public Handler(Looper looper, Callback callback) {
mLooper = looper;
mQueue = looper.mQueue;
mCallback = callback;
}
(二)消息的发送
handler如何把消息放入消息队列中吗?runable中的run()是如何被调用的????
1. 发送消息
public final boolean sendMessage(Message msg)
{
return sendMessageDelayed(msg, 0);
}
public final boolean sendMessageDelayed(Message msg, long delayMillis)
{
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
public boolean sendMessageAtTime(Message msg, long uptimeMillis)
{
boolean sent = false;
MessageQueue queue = mQueue;
if (queue != null) {
msg.target = this;
sent = queue.enqueueMessage(msg, uptimeMillis);
}
else {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
}
return sent;
}
MessageQueue queue = mQueue的消息队列是我们在创建消息循环Looper的时候创建的,这个可以看Handler的构造函数;
target是Handler类型的, 这样消息就可以把消息发送给各自的handler,这样就不会出现多个handler而消息换混乱的问题。。。。
他们的扩展函数:
1.
public final boolean sendEmptyMessage(int what)
{
return sendEmptyMessageDelayed(what, 0);
}
2.
public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
Message msg = Message.obtain();
msg.what = what;
return sendMessageDelayed(msg, delayMillis);
}
这里我们就可以看到,这里就吧what值付给类消息,再调用sendMessageDelayed函数发送消息,只是一个特殊情况而已。。。
3.
public final boolean post(Runnable r)
{
return sendMessageDelayed(getPostMessage(r), 0);
}
4.
public final boolean postAtTime(Runnable r, long uptimeMillis)
{
return sendMessageAtTime(getPostMessage(r), uptimeMillis);
}
public final boolean postAtTime(Runnable r, Object token, long uptimeMillis)
{
return sendMessageAtTime(getPostMessage(r, token), uptimeMillis);
}
5.
public final boolean postDelayed(Runnable r, long delayMillis)
{
return sendMessageDelayed(getPostMessage(r), delayMillis);
}
不难发现,3,4,5的函数中叶是同sendMessageAtTime来是实现,这里最重要的就是调用了getPostMessage()
private final Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}
这里其实也就把runbale赋值给了Message中Runnable callback(这里要注意,这个callback和handler中callback(ICallback)是不一样的)。
(三)从Handler中获取消息消息
public final Message obtainMessage()
{
return Message.obtain(this);
}
还有四个同名的函数,他们的是实现都是通过Message.obtain()来实现的;
public static Message obtain(Message orig) {
Message m = obtain();
m.what = orig.what;
m.arg1 = orig.arg1;
m.arg2 = orig.arg2;
m.obj = orig.obj;
m.replyTo = orig.replyTo;
if (orig.data != null) {
m.data = new Bundle(orig.data);
}
m.target = orig.target;
m.callback = orig.callback;
return m;
}
/**
* Return a new Message instance from the global pool. Allows us to
* avoid allocating new objects in many cases.
*/
public static Message obtain() {
synchronized (sPoolSync) {
if (sPool != null) {
Message m = sPool;
sPool = m.next;
m.next = null;
sPoolSize--;
return m;
}
}
return new Message();
}
不难发现,消息是从消息 池中取出来的,如果消息池中没有消息,则才回去此新生成一个;
当然,message中obtain方法也是有很多同名函数的,这里就不举例了。。。。
(四)消息的派发
/**
* Handle system messages here.
*/
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
这里有三种情况来处理消息:
(1)message中callback(Runable)不为空,即通过post把runable对象置入消息中;
private final void handleCallback(Message message) {
message.callback.run();
}
这里就调用了需要实现的runable对象中的run()函数;
(2)mCallback(ICallback)不为空
public interface Callback {
public boolean handleMessage(Message msg);
}
我们只要实现这个接口就可以了。。。这个方法,好像使用的很少,不知哪位大师,可否指教下,什么情况下使用。。。。
(3)(1)(2)都不满足的请款下,就调用了handleMesage函数
public void handleMessage(Message msg) {
}
最后我们分析下消息循环Looper
1.构造函数
private Looper() {
mQueue = new MessageQueue();
mRun = true;
mThread = Thread.currentThread();
}
Looper的构造函数是私有的,在构造中生成了队列和获取当前的线程,
这里其实要注意的,发现前面文章中说的是有问题的,我们不难发现,如果我们在主线程中创建默认的handler,他其实创建获和取的消息循环的线程都是在主线程中,因为
public static Looper myLooper() {
return sThreadLocal.get();
}
而sThread的循环是new Looper实现的,而Lopper中就使用主线程。。。。所以 我们前面说错了,这个线程虽然由系统产生,但是他也是主线程,所以以后操作最好使用ThreadHandler.
2.loop实现消息的死循环
public static void loop() {
Looper me = myLooper();
MessageQueue queue = me.mQueue;
。。。。。。。。。。。。。。。
while (true) {
Message msg = queue.next(); // might block
if (msg != null) {
if (msg.target == null) {
// No target is a magic identifier for the quit message.
return;
}
。。。。。。。。。
msg.target.dispatchMessage(msg);
msg.recycle();
}
}
}
这个函数式由系统调用的,所以我们才会说在主线程创建Hanler,不阻塞组线程,并且是异步的。。。。
这里最主要是派发消息和消息的回收。。。
以上就关于handler的源码解析,有问题,或者说错的请指教。。。。。。。