您的位置:首页 > 其它

Handler消息机制源码解析

2016-05-26 17:15 351 查看
1.

Looper.prepareMainLooper();
ActivityThread thread = new
ActivityThread();
thread.attach(false);
if (sMainThreadHandler
== null) {
    sMainThreadHandler
= thread.getHandler();
}
if (false) {
    Looper.myLooper().setMessageLogging(new
            LogPrinter(Log.DEBUG,
"ActivityThread"));
}
Looper.loop();
/************************************************/
public static void
prepareMainLooper() {
    prepare(false);
    synchronized (Looper.class) {
        if
(sMainLooper
!= null) {
            throw new
IllegalStateException("The main Looper has already been prepared.");
        }
        sMainLooper
= myLooper(); //设置主looper
    }
}
// looper是通过prepare进行实例化
private static void
prepare(boolean
quitAllowed) {
    if
(sThreadLocal.get() !=
null) {
        throw new
RuntimeException("Only one Looper may be created per thread");
    }
    sThreadLocal.set(new
Looper(quitAllowed));
}
private
Looper(boolean
quitAllowed) {
    mQueue
= new
MessageQueue(quitAllowed);
    mThread
= Thread.currentThread();
}
消息队列和当前线程就绑定在一起了,继续进行无限玄幻,阻塞队列,取出消息,响应消息
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;
}
msg.target.dispatchMessage(msg);
}
 
 

2. 例子:

Acitivity中实例化Handler

private
Handler mHandler
= new
Handler() {
    @Override
    public void
handleMessage(Message msg) {
        super.handleMessage(msg);
        int signal = msg.arg1;
        switch (signal) {
            case
0:
                progressView.setProgress(0);
                break;
        }
    }
};
点击
case
R.id.btn_enen:
    Message message = new
Message();
    message.arg1
= 0;
    mHandler.sendMessage(message);
    break;
在handler构造函数中,获取到和当前线程绑定的looper,也就是主线程的looper对象,threadlocal就是和当前线程绑定数据的工具,是与线程对应的,不同线程绑定同一个变量,只影响在当前线程的值,当前activity的handler就获得了主线程的looper对象,接下来就可以用handler发送消息了,

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;
mAsynchronous = async;
public static
Looper myLooper() {
    return
sThreadLocal.get();
}
发送消息,就是让消息进入主线程的消息队列中,有一部就是给当前handler设置给message的target变量

Handler

private boolean
enqueueMessage(MessageQueue queue,
Message msg, long
uptimeMillis) {
    msg.target
= this;
    if (mAsynchronous) {
        msg.setAsynchronous(true);
    }
    return
queue.enqueueMessage(msg,
uptimeMillis);
}
设置了target的handler以后,在looper.loop无限循环中,就会调用dispatchMessage()

msg.target.dispatchMessage(msg);
在dispatchMessage function调用被activity的handler复写的handleMessage(),就完成了通信,

Handler
public void
dispatchMessage(Message msg) {
    if
(msg.callback
!= null) {
        handleCallback(msg);
    }
else {
        if
(mCallback
!= null) {
            if
(mCallback.handleMessage(msg)) {
                return;
            }
        }
        handleMessage(msg);
    }
}
有个地方就是如果设置了message的回调,就会执行message的回调,不会执行handleMessage(),如果没有设置message的回调,但设置了handler的callback,就会优先执行handler的callback,看返回值,如果返回true,就代表已经处理了,如果返回false,就继续执行handler的handlMessage()

private
Handler mHandler
= new
Handler(new
Handler.Callback() {
    @Override
    public boolean
handleMessage(Message msg) {
        return false;
    }
}) {
    @Override
    public void
handleMessage(Message msg) {
        super.handleMessage(msg);
        int signal = msg.arg1;
        switch (signal) {
            case
0:
                progressView.setProgress(0);
                break;
        }
    }
};
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: