您的位置:首页 > 产品设计 > UI/UE

handler messagequeue looper之间最清楚的讲解

2016-12-19 20:47 232 查看


首先来说我们一般在主线程中创建handler,再子线程中发送消息,经过一系列的操作,最后在主线程中handleMessage()方法处理

子线程中 发送消息方法 sendMessage() —->sendMessageDelayed()—->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);
}


调用enqueueMessage

private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}


enqueueMessage这个方法就是向MessageQueue中添加消息

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;
}
msg.markInUse();
msg.when = when;
Message p = mMessages;
boolean needWake;
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;
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;
}


****enqueueMessage这个方法主要的功能就是向MessageQueue中添加Message

static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();


每一个主线程都会有一个looper对象,looper对象存在于ThreadLocal中,保证了线程数据的隔离

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));
}


初始化Looper

/**
* Return the Looper object associated with the current thread.  Returns
* null if the calling thread is not associated with a Looper.
*/
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}


获取当前的looper



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();

}

}

“`

这个方法的意思就是从messageQueue中取出Message,并转发给主线程的handler,进行处理

我这里根据handler的理解,在Java层实现了handler的机制,你如果搞清楚我的Java代码,我觉得应该对handler有一个不错的理解

这里是我在frameWork层对handler的实现

如果有不对的地方欢迎提出问题,一块交流学习,我也是刚刚参加工作,谢谢
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: