本文主要是介绍Looper,Handler,MessageQueue的分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
在这里插入图片描述
Android消息机制解析
ActivityThread:
main(){....Looper.prepareMainLooper();....// 创建ActivityThread对象,并绑定到AMSActivityThread thread = new ActivityThread();// 建立Binder通道,创建新线程,一般的应用程序都不会是system,因此设置false,会绑定到AMSthread.attach(false, startSeq);....Looper.loop();//可以保证线程一直存活throw new RuntimeException("Main thread loop unexpectedly exited");
}
Looper:
prepareMainLooper(){// 绑定当前线程和Looper ---- 面试题一:一个线程中可以有几个Looper对象?prepare(false) // 将sMainLooper赋值synchronized (Looper.class) {if (sMainLooper != null) {throw new IllegalStateException("The main Looper has already been prepared.");}sMainLooper = myLooper();}
}private static void prepare(boolean quitAllowed) {// 检查当前线程的ThreadLocal中是否存储了Looper对象,如果有的抛异常if (sThreadLocal.get() != null) {throw new RuntimeException("Only one Looper may be created per thread");}// 没有,就创建一个Looper对象,并存储在当前线程的ThreadLocal中sThreadLocal.set(new Looper(quitAllowed));
}// Looper的构造方法
private Looper(boolean quitAllowed) {// 创建消息队列mQueue = new MessageQueue(quitAllowed);mThread = Thread.currentThread();
}public static void loop() {// 检测当前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; for (;;) { // 为什么不会一直占用cpu的资源Message msg = queue.next(); // might block// 当queue中没有消息时,则会调用 native void nativePollOnce(long, int),进行休眠// ....try {// 处理消息 ---- 此处见Handler-enqueueMessage,即调用的是Handler中的dispatchMessagemsg.target.dispatchMessage(msg);if (observer != null) {observer.messageDispatched(token, msg);}dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0;} catch (Exception exception) {if (observer != null) {observer.dispatchingThrewException(token, msg, exception);}throw exception;} finally {ThreadLocalWorkSource.restore(origWorkSource);if (traceTag != 0) {Trace.traceEnd(traceTag);}}// ....}
}
MessageQueue
// 取消息
Message next() {for (;;) {// ....// nextPollTimeoutMillis // -1 则阻塞线程,直到被唤醒// 0 立即返回,不阻塞线程// 等待 nextPollTimeoutMillis 的时间nativePollOnce(ptr, nextPollTimeoutMillis);// ....}
}
// 消息加入队列
boolean enqueueMessage(Message msg, long when) {synchronized (this) {// ....// 唤醒线程if (needWake) {nativeWake(mPtr);}}return true;
}
Handler
public Handler(@Nullable Callback callback, boolean async) {// 获取当前线程的LoopermLooper = Looper.myLooper();if (mLooper == null) {throw new RuntimeException("Can't create handler inside thread " + Thread.currentThread()+ " that has not called Looper.prepare()");}// 获取当前的消息队列mQueue = mLooper.mQueue;mCallback = callback;mAsynchronous = async;
}
// 所有的方法最终都会执行这个方法
public boolean sendMessageAtTime(@NonNull Message msg, long uptimeMillis) {// 将消息加入当前线程Looper对象中的消息队列中MessageQueue queue = mQueue;return enqueueMessage(queue, msg, uptimeMillis);
}
private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,long uptimeMillis) {// 执行器就是当前的handlermsg.target = this;// 加入消息队列return queue.enqueueMessage(msg, uptimeMillis);
}
public void dispatchMessage(@NonNull Message msg) {if (msg.callback != null) {handleCallback(msg);} else {// Handler 构造方法中的回调if (mCallback != null) {if (mCallback.handleMessage(msg)) {return;}}handleMessage(msg);}
}
// 提供开发者复写
public void handleMessage(@NonNull Message msg) {}
private static void handleCallback(Message message) {// message callback 是Runnable的子类message.callback.run();
}
这篇关于Looper,Handler,MessageQueue的分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!