Handler,MessageQueue,Runnable与Looper
Posted xuguoli_beyondboy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Handler,MessageQueue,Runnable与Looper相关的知识,希望对你有一定的参考价值。
三者关系
Handler是处理消息或发送消息,MessageQueue存储消息,Runnable安排执行任务,Looper循环MessageQueue消息队列,并取出消息到给制定Handler处理。其三者具体关系如下:
- 每个Thread只对应一个Looper。
- 每个Looper只对应一个MessageQueue。
- 每个MessageQueue中有N个Message。
- 每个Message中最多指定一个Handler来处里消息(处理线程为Looper绑定的线程)。
采用这机制对消息进行处理,有下面两点好处: - 在多线程并发执行的同时,做出一些改变的时候,这方法可以避免了一些判断条件。
- 一般来说,Thread一旦完成执行任务,就不可以重复执行新的任务,而采用这种机制它可以让Thread可以在后台重复执行任务,而不用创建新的Thread实例,因为它的生命周期是伴随Looper的生命周期,只要Looper不调用
quit
方法,Thread的生命周期就不会结束。
Handler
handler这个角色起着两个重要作用,一是:处理Message;二是:将某个Message压入MessageQueue。
构造函数源码分析:
//默认设置Looper和MessageQueue
public Handler(Callback callback, boolean async)
if (FIND_POTENTIAL_LEAKS)
final Class<? extends Handler> klass = getClass();
//检查Handler是否是时静态内部类,静态实例,静态匿名类,不是发出内存泄漏警告
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());
//获得当前线程的Looper
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;
//自定义设置Looper和MessageQueue
public Handler(Looper looper, Callback callback, boolean async)
mLooper = looper;
mQueue = looper.mQueue;
mCallback = callback;
mAsynchronous = async;
从源码分析可以看出,如果你创建Handler实例时,当地线程没有Looper实例且有没有传入Looper实例,就会抛出Can't create handler inside thread that has not called Looper.prepare()
异常。
发送消息源码分析:
//发送任务
public final boolean post(Runnable r)
return sendMessageDelayed(getPostMessage(r), 0);
//发送延时执行任务
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);
//发送延时任务
public final boolean postDelayed(Runnable r, long delayMillis)
return sendMessageDelayed(getPostMessage(r), delayMillis);
//发送下一个将要执行的任务
public final boolean postAtFrontOfQueue(Runnable r)
return sendMessageAtFrontOfQueue(getPostMessage(r));
//将Runnable封装成Message消息
private static Message getPostMessage(Runnable r)
//从消息池获取Message
Message m = Message.obtain();
m.callback = r;
return m;
//定时发送消息到MessageQueue
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)
//绑定处理消息处理的Handler
msg.target = this;
if (mAsynchronous)
msg.setAsynchronous(true);
//插入消息到MessageQueue
return queue.enqueueMessage(msg, uptimeMillis);
//插入消息
boolean enqueueMessage(Message msg, long when)
//检查该消息是否有对应的Handler
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)
//检查Looper循环是否已停止
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;
//检查是否是msg头部消息(即原本消息队列为空)或处于空闲等待状态,如果是唤醒休眠的事件队列
if (p == null || when == 0 || when < p.when)
//m该sg为头部
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;
//寻找msg执行后的下一个执行消息
for (;;)
prev = p;
p = p.next;
//若到消息队列结束或下一个将要执行的消息大于msg的延时时间,
if (p == null || when < p.when)
break;
//如果是异步,则不用唤醒
if (needWake && p.isAsynchronous())
needWake = false;
//下一个将要执行的message对象
msg.next = p;
prev.next = msg;
// We can assume mPtr != 0 because mQuitting is false.
if (needWake)
//调用本地方法唤醒主线程
nativeWake(mPtr);
return true;
从源码分析来看,发送消息事,传送的Runnable对象会被封装成Message对象,插入到消息队列。
处理消息源码分析:
//分发消息
public void dispatchMessage(Message msg)
if (msg.callback != null)
//执行Runnable任务
handleCallback(msg);
else
//new Callback任务
if (mCallback != null)
if (mCallback.handleMessage(msg))
return;
//执行我们重写的handlerMessage方法
handleMessage(msg);
//执行Runnable的run方法
private static void handleCallback(Message message)
message.callback.run();
//回调接口
public interface Callback
public boolean handleMessage(Message msg);
从源码分析来看,Handler处理消息过程如图:
MessageQueue
构造函数源码分析:
//调用本地方法初始化
MessageQueue(boolean quitAllowed)
//是否运行线程退出Looper循环,主线程默认不可以退出Looper循环
mQuitAllowed = quitAllowed;
mPtr = nativeInit();
//本地方法实现
static jint android_os_MessageQueue_nativeInit(JNIEnv* env, jclass clazz)
//创建本地NativeMessageQueue对象
NativeMessageQueue* nativeMessageQueue = new NativeMessageQueue();
if (!nativeMessageQueue)
jniThrowRuntimeException(env, "Unable to allocate native queue");
return 0;
//增加引用计数
nativeMessageQueue->incStrong(env);
return reinterpret_cast<jint>(nativeMessageQueue);
本地的NativeMessageQueue构造方法源码分析:
NativeMessageQueue::NativeMessageQueue() : mInCallback(false), mExceptionObj(NULL)
//获取本地方法的Looper对象
mLooper = Looper::getForThread();
if (mLooper == NULL)
//没有创建本地Looper对象,并epoll中监听回调不允许为空
mLooper = new Looper(false);
Looper::setForThread(mLooper);
本地Looper的构造方法源码分析:
Looper::Looper(bool allowNonCallbacks) :
mAllowNonCallbacks(allowNonCallbacks), mSendingMessage(false),
mResponseIndex(0), mNextMessageUptime(LLONG_MAX)
//存储管道读写端的句柄
int wakeFds[2];
int result = pipe(wakeFds);
LOG_ALWAYS_FATAL_IF(result != 0, "Could not create wake pipe. errno=%d", errno);
mWakeReadPipeFd = wakeFds[0];
mWakeWritePipeFd = wakeFds[1];
//创建管道读端的句柄
result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK);
LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake read pipe non-blocking. errno=%d",
errno);
//创建管道写端的句柄
result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK);
LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake write pipe non-blocking. errno=%d",
errno);
mIdling = false;
// 创建epoll句柄,并传入能监听文件句柄的最大数量.
mEpollFd = epoll_create(EPOLL_SIZE_HINT);
LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance. errno=%d", errno);
struct epoll_event eventItem;
memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union
eventItem.events = EPOLLIN;
eventItem.data.fd = mWakeReadPipeFd;
//注册管道监听,一旦管道有内容可读,就唤醒正在等待管道中的线程
result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, & eventItem);
LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake read pipe to epoll instance. errno=%d",
errno);
从源码分析可以知道,其进程通信采用管道机制和linux的epoll机制,对于管道机制来说,一般的使用方式就是,一个线程通过读文件描述符中来读管道的内容,当管道没有内容时,这个线程就会进入等待状态,而另外一个线程通过写文件描述符来向管道中写入内容,写入内容的时候,如果另一端正有线程正在等待管道中的内容,那么这个线程就会被唤醒。至于如何唤醒是借用通过linux的epoll机制。linux的epoll机制可以参考下面文章了解:
http://blog.csdn.net/zhaozhanyong/article/details/5410887
从上面源勉分析来看,java层的MessageQueue,Looper和native层的MessageQueue,Looper一一对应,其关系如图:
Looper
Looper的创建源码分析:
//普通线程调用其创建Looper对象,其Looper循环可以退出
public static void prepare()
prepare(true);
//UI线程调用其创建Looper对象,UI线程默认调用,其Looper循环不可以退出
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对象,quitAllowed参数控制Looper循环是否可以退出
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构造方法
private Looper(boolean quitAllowed)
//创建消息队列
mQueue = new MessageQueue(quitAllowed);
//绑定本线程
mThread = Thread.currentThread();
从源码看出,Looper对象会通过内部构造方法绑定一个消息队列,而普通线程是通过Looper.prepare()
方法创建Looper和MessageQueue对象,且默认Looper循环可以退出,而主线程是通过Looper.prepareMainLooper()
创建对象Looper和MessageQueue对象,且默认Looper循环不可以退出。
循环消息源码分析:
//循环取出消息,直到调用quit()方法退出
public static void loop()
final Looper me = myLooper();
//检查是否有Looper对象
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
//当调用了quit方法
if (msg == null)
//退出循环
return;
// This must be in a local variable, in case a UI event sets the logger
//Log日志对象
Printer logging = me.mLogging;
if (logging != null)
logging.println(">>>>> Dispatching to " + msg.target + " " +
msg.callback + ": " + msg.what);
//进行消息处理
msg.target.dispatchMessage(msg);
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();
从源码分析可以看出,Looper实际通过MessageQueue.next()
方法取出消息。
MessageQueue.next()取出消息的方法源码分析:
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.
//验证epoll句柄是否创建成功
final long ptr = mPtr;
if (ptr == 0)
return null;
//运行空闲Handler的数量
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;
// 如果当前消息非空,但是当前消息的处理handle是空;则获取第一个异步消息
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());
//当当前消息非空,且有对应处理handle或当前消息的是异步消息
if (msg != null)
if (now < msg.when)
// 如果当前消息还不到执行,就设置一个和现在时间差的等待执行时间
nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);
//如果该消息到了执行时间
else
// Got a message.
mBlocked = false;
//当当前执行消息为取出的第一个异步消息,删除异步消息,连接异步消息下一个消息
if (prevMsg != null)
prevMsg.next = msg.next;
//当当前执行消息是有对应的handle消息时,连接一下个消息
else
mMessages = msg.next;
msg.next = null;
if (DEBUG) Log.v(TAG, "Returning message: " + msg);
//标记该消息对象被使用
msg.markInUse();
return msg;
else
// 没有消息时
nextPollTimeoutMillis = -1;
// Process the quit message now that all pending messages have been handled.
if (mQuitting)
dispose();
return null;
// If first time idle, then get the number of idlers to run.
// Idle handles only run if the queue is empty or if the first message
// in the queue (possibly a barrier) is due to be handled in the future.
if (pendingIdleHandlerCount < 0
&& (mMessages == null || now < mMessages.when))
//获取正在运行的空闲Handler数目
pendingIdleHandlerCount = mIdleHandlers.size();
if (pendingIdleHandlerCount <= 0)
//没有空闲的Handler正在运行,那么Looper会阻塞等待
mBlocked = true;
continue;
//第一次调用next()方法时候会创建四个空闲的Handler对象实例
if (mPendingIdleHandlers == null)
mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];
mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers);
//只在第一次调用该next()方法时,才会执行到下面代码去运行空闲的Handlers
for (int i = 0; i < pendingIdleHandlerCount; i++)
final IdleHandler idler = mPendingIdleHandlers[i];
mPendingIdleHandlers[i] = null; // release the reference to the handler
//是否保持该空闲Handler运行的标记
boolean keep = false;
try
keep = idler.queueIdle();
catch (Throwable t)
Log.wtf(TAG, "IdleHandler threw exception", t);
//停止该空闲Handler的运行
if (!keep)
synchronized (this)
mIdleHandlers.remove(idler);
// 设置空闲Handler数量为0,防止再次创建和运行空闲Handler
pendingIdleHandlerCount = 0;
//通过运行空闲的Handler去等待新的Message到来,而不是通过阻塞状态
nextPollTimeoutMillis = 0;
本地方法的pollOnce源码分析:
static void android_os_MessageQueue_nativePollOnce(JNIEnv* env, jclass clazz,
jint ptr, jint timeoutMillis)
NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);
//调用本地MessageQeueu的pollOnce方法
nativeMessageQueue->pollOnce(env, timeoutMillis);
//本地轮询方法的实现
void NativeMessageQueue::pollOnce(JNIEnv* env, int timeoutMillis)
mInCallback = true;
//调用本地Looper的pollOnce方法
mLooper->pollOnce(timeoutMillis);
mInCallback = false;
if (mExceptionObj)
env->Throw(mExceptionObj);
env->DeleteLocalRef(mExceptionObj);
mExceptionObj = NULL;
//本地Looper的轮询方法实现,获取下一个执行的消息,以唤醒线程
int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData)
int result = 0;
//这里很多地方看不太懂,就直接看pollInner(timeoutMillis)方法
for (;;)
while (mResponseIndex < mResponses.size())
const Response& response = mResponses.itemAt(mResponseIndex++);
int ident = response.request.ident;
if (ident >= 0)
int fd = response.request.fd;
int events = response.events;
void* data = response.request.data;
#if DEBUG_POLL_AND_WAKE
ALOGD("%p ~ pollOnce - returning signalled identifier %d: "
"fd=%d, events=0x%x, data=%p",
this, ident, fd, events, data);
#endif
if (outFd != NULL) *outFd = fd;
if (outEvents != NULL) *outEvents = events;
if (outData != NULL) *outData = data;
return ident;
if (result != 0)
#if DEBUG_POLL_AND_WAKE
ALOGD("%p ~ pollOnce - returning result %d", this, result);
#endif
if (outFd != NULL) *outFd = 0;
if (outEvents != NULL) *outEvents = 0;
if (outData != NULL) *outData = NULL;
return result;
result = pollInner(timeoutMillis);
本地Looper的pollInner()源码分析:
int Looper::pollInner(int timeoutMillis)
#if DEBUG_POLL_AND_WAKE
ALOGD("%p ~ pollOnce - waiting: timeoutMillis=%d", this, timeoutMillis);
#endif
// Adjust the timeout based on when the next message is due.
if (timeoutMillis != 0 && mNextMessageUptime != LLONG_MAX)
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
int messageTimeoutMillis = toMillisecondTimeoutDelay(now, mNextMessageUptime);
if (messageTimeoutMillis >= 0
&& (timeoutMillis <0 || messageTimeoutMillis < timeoutMillis))
timeoutMillis = messageTimeoutMillis;
#if DEBUG_POLL_AND_WAKE
ALOGD("%p ~ pollOnce - next message in %lldns, adjusted timeout: timeoutMillis=%d",
this, mNextMessageUptime - now, timeoutMillis);
#endif
// Poll.
int result = ALOOPER_POLL_WAKE;
mResponses.clear();
mResponseIndex = 0;
struct epoll_event eventItems[EPOLL_MAX_EVENTS];
//等待消息队列的事件发生,就是被监听的消息管道,一旦管道有可读内容,线程就会被唤醒
int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis);
// Acquire lock.
mLock.lock();
//轮询监听出错,则直接跳到Done处.
if (eventCount <0)
if (errno == EINTR)
goto Done;
ALOGW("Poll failed with an unexpected error, errno=%d", errno);
result = ALOOPER_POLL_ERROR;
goto Done;
// 超时,就是在一定超时设置时间范围内,还没有产生可读内容事件,则直接跳到Done处。
if (eventCount == 0)
#if DEBUG_POLL_AND_WAKE
ALOGD("%p ~ pollOnce - timeout", this);
#endif
result = ALOOPER_POLL_TIMEOUT;
goto Done;
// Handle all events.
#if DEBUG_POLL_AND_WAKE
ALOGD("%p ~ pollOnce - handling events from %d fds", this, eventCount);
#endif
// 如果有可读内容事件发生,则逐个取出消息,如果是是写事件(EPOLLIN),则调用awoken()唤醒线程
for (int i = 0; i <eventCount; i++)
int fd = eventItems[i].data.fd;
uint32_t epollEvents = eventItems[i].events;
if (fd == mWakeReadPipeFd)
if (epollEvents & EPOLLIN)
awoken();
else
ALOGW("Ignoring unexpected epoll events 0x%x on wake read pipe.", epollEvents);
else
ssize_t requestIndex = mRequests.indexOfKey(fd);
if (requestIndex >= 0)
int events = 0;
if (epollEvents & EPOLLIN) events |= ALOOPER_EVENT_INPUT;
if (epollEvents & EPOLLOUT) events |= ALOOPER_EVENT_OUTPUT;
if (epollEvents & EPOLLERR) events |= ALOOPER_EVENT_ERROR;
if (epollEvents & EPOLLHUP) events |= ALOOPER_EVENT_HANGUP;
pushResponse(events, mRequests.valueAt(requestIndex));
else
ALOGW("Ignoring unexpected epoll events 0x%x on fd %d that is "
"no longer registered.", epollEvents, fd);
Done: ;
// Invoke pending message callbacks.
mNextMessageUptime = LLONG_MAX;
while (mMessageEnvelopes.size() != 0)
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0);
if (messageEnvelope.uptime <= now)
// Remove the envelope from the list.
// We keep a strong reference to the handler until the call to handleMessage
// finishes. Then we drop it so that the handler can be deleted *before*
// we reacquire our lock.
// obtain handler
sp<MessageHandler> handler = messageEnvelope.handler;
Message message = messageEnvelope.message;
mMessageEnvelopes.removeAt(0);
mSendingMessage = true;
mLock.unlock();
#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS
ALOGD("%p ~ pollOnce - sending message: handler=%p, what=%d",
this, handler.get(), message.what);
#endif
handler->handleMessage(message);
// release handler
mLock.lock();
mSendingMessage = false;
result = ALOOPER_POLL_CALLBACK;
else
// The last message left at the head of the queue determines the next wakeup time.
mNextMessageUptime = messageEnvelope.uptime;
break;
// Release lock.
mLock.unlock();
// Invoke all response callbacks.
for (size_t i = 0; i <mResponses.size(); i++)
Response& response = mResponses.editItemAt(i);
if (response.request.ident == ALOOPER_POLL_CALLBACK)
int fd = response.request.fd;
int events = response.events;
void* data = response.request.data;
#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS
ALOGD("%p ~ pollOnce - invoking fd event callback %p: fd=%d, events=0x%x, data=%p",
this, response.request.callback.get(), fd, events, data);
#endif
int callbackResult = response.request.callback->handleEvent(fd, events, data);
if (callbackResult == 0)
removeFd(fd);
// Clear the callback reference in the response structure promptly because we
// will not clear the response vector itself until the next poll.
response.request.callback.clear();
result = ALOOPER_POLL_CALLBACK;
return result;
//读取管道内容,来唤醒线程
void Looper::awoken()
#if DEBUG_POLL_AND_WAKE
ALOGD("%p ~ awoken", this);
#endif
char buffer[16];
ssize_t nRead;
do
//唤醒线程
nRead = read(mWakeReadPipeFd, buffer, sizeof(buffer));
while ((nRead == -1 && errno == EINTR) || nRead == sizeof(buffer));
从源码分析来看,pollInner()就是先通过epoll_wait()进入空闲等待状态,等待消息队列的管道上的消息(IO事件),如果有消息待处理(即管道上有IO写事件发生,写事件是EPOLLIN类型),则调用awoken()(通过往管道中读数据来使处于空闲等待状态的主线程继续运行)将消息读取出来.
总结
总过上面java层到native层的分析,可以很清楚知道Handler,MessageQueue,Looper在java层和native层之间的关系和协作,其整个过程如图:
创建实例过程:
取出消息过程:
参考资料:
http://blog.nikitaog.me/2014/10/11/android-looper-handler-handlerthread-i/
http://blog.nikitaog.me/2014/10/18/android-looper-handler-handlerthread-ii/
http://wangkuiwu.github.io/2014/08/26/MessageQueue/
http://www.programering.com/a/MjM2QDMwATc.html
以上是关于Handler,MessageQueue,Runnable与Looper的主要内容,如果未能解决你的问题,请参考以下文章
Android中的Handler, Looper, MessageQueue和Thread对应关系
Android源码学习 Handler之MessageQueue
Handler类和Handler,Loop,MessageQueue的工作原理