源码基于 Android S AOSP,源码在线查看地址: cs.android.com/android/pla…
线程间通信在 Android 系统中应用十分广接口英文泛,本文是一个系列文章,主要梳理了Android Java层的线程间通信机制-Handler。
- Android 线程间通信 – Java 层
- Android 线程间通信 – Java 层 – MessagePool
- Android 线程间通信 – Native 层
一个 Java 层简单的 H变量andler 示appearance例如下:
public void egHandler() { Looper.prepare(); Looper.loop(); Handler handler = new Handler() { @Override public void handleMessage(@NonNull Message msg) { // TODO; 处理 Event } }; new Thread() { @Override public void run() { Message msg = new Message(); msg.what = 0; handler.sendMessage(msg); } }.start(); }
Java 层变量名的线程通信主要涉及到了Handler、MessageQueue、Message、Looper。
主线程创建的时候默认会执行Looper.pr源码网站epare()、Looper.线程池loop()方法,即默认会创建Looper
L变量名的命名规则ooper
源码路径frameworks/base/源码编辑器手机版下载core/java/android/os/Looper.java
Looper.prepare
public static void prepare() { // 调用Looper.prepare prepare(true); } private static void prepare(boolean quitAllowed) { // 默认传入 true, 允许中断 // 从ThreadLocal中尝试拿出Looper对象 if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } // ThreadLocal中没有Looper对象则进行创建 sThreadLocal.set(new Looper(quitAllowed)); }
Looper.Looper
private Looper(boolean quitAllowed) { // 搞出来一个MessageQueue mQueue = new MessageQueue(quitAllowed); // 用一个变量保存当前线程(对应上面的示例也就是主线程) mThread = Thread.currentThread(); }
MessageQueue.MessageQueue
MessageQueue(boolean quitAllowed) { // 接收Looper传进的参数,默认允许中断 mQuitAllowed = quitAllowed; // 初始化native方法,下一篇文章会说到 mPtr = nativeInit(); }
Looper.loop
@SuppressWarnings("AndroidFrameworkBinderIdentity") public static void loop() { // 从当前线程拿到 looper 对象 final Looper me = myLooper(); if (me == null) { throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); } if (me.mInLoop) { Slog.w(TAG, "Loop again would have the queued messages be executed" + " before this one completed."); } // 标识 Looper 开始 loop me.mInLoop = true; // 清空远程调用端的pid和uid,使用本地进程的pid和uid代替 Binder.clearCallingIdentity(); final long ident = Binder.clearCallingIdentity(); // Allow overriding a threshold with a system prop. e.g. // adb shell 'setprop log.looper.1000.main.slow 1 && stop && start' final int thresholdOverride = SystemProperties.getInt("log.looper." + Process.myUid() + "." + Thread.currentThread().getName() + ".slow", 0); me.mSlowDeliveryDetected = false; // 无线循环,调用loopOnce for (;;) { if (!loopOnce(me, ident, thresholdOverride)) { return; } } }
Looper.myLooper
public static @Nullable Looper myLooper() { // 从当前线程中拿出 Looper 对象 return sThreadLocal.get(); }
Loo线程是什么意思per.loopOnce
@SuppressWarnings("AndroidFrameworkBinderIdentity") private static boolean loopOnce(final Looper me, final long ident, final int thresholdOverride) { Message msg = me.mQueue.next(); // 从MessageQueue中取出Message,当MessageQueue中没有消息时,此处会阻塞 // ...... // Make sure the observer won't change while processing a transaction. final Observer observer = sObserver; // ...... Object token = null; if (observer != null) { // 当注册了观察者时,调用观察者messageDispatchStarting方法 token = observer.messageDispatchStarting(); } long origWorkSource = ThreadLocalWorkSource.setUid(msg.workSourceUid); try { // 调用消息的dispatchMessage方法,默认为Handler.dispatchMessage方法 msg.target.dispatchMessage(msg); if (observer != null) { // 调用观察者 messageDispatched方法 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); } } // ...... // 回收消息 msg.recycleUnchecked(); return true; }
Looper.java中还有一些不常用的方法线程和进程的区别是什么
Looper.线程数越多越好吗myLooper
public static @Nullable Looper myLooper() { return sThreadLocal.get(); }
Looper.myQueue
public static @NonNull MessageQueue myQueue() { return myLooper().mQueue; }
Looper.isCurrentThread
public boolean isCurrentThread() { return Thread.currentThread() == mThread; }
Looper.quit
public void quit() { mQueue.quit(false); }
Looper.quitSafely
public void quitSafely() { mQueue.quit(true); }
Looper.getQueue
public @NonNull MessageQueue getQueue() { return mQueue; }
Observer
在上线程安全面Looper.loopOnce中提到了Observ线程数越多越好吗er,该接口定义在Looper.java中,共三个方接口英文法
public interface Observer { Object messageDispatchStarting(); void messageDispatched(Object token, Message msg); void dispatchingThrewException(Object token, Message msg, Exception exception); }
可以实现该接口,通过setObserver方法注册进去
public static void setObserver(@Nullable Observer observer) { sObserver = observer; }
Handler
源码路径源码时代:frameworks/base/core/java源码之家/android/os/Handler.java
Handler.Handle源码编辑器手机版下载r
@Deprecated public Handler() { this(null, false); } @Deprecated public Handler(@Nullable Callback callback) { this(callback, false); } // 指定Looper public Handler(@NonNull Looper looper) { this(looper, null, false); } // 指定Looper和Callback public Handler(@NonNull Looper looper, @Nullable Callback callback) { this(looper, callback, false); } public Handler(@Nullable Callback callback, boolean async) { // ...... mLooper = 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; } @UnsupportedAppUsage // 此注解表示App无法使用该构造方法 public Handler(@NonNull Looper looper, @Nullable Callback callback, boolean async) { mLooper = looper; mQueue = looper.mQueue; mCallback = callback; mAsynchronous = async; }
Handle接口和抽象类的区别r.sendMessage
public final boolean sendMessage(@NonNull Message msg) { return sendMessageDelayed(msg, 0); } public final boolean sendMessageDelayed(@NonNull Message msg, long delayMillis) { if (delayMillis < 0) { delayMillis = 0; } return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis); } // 定时发送消息,sendMessage代表now发送消息 public boolean sendMessageAtTime(@NonNull 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; } // 调用MessageQueue方法,将Message加入到MessageQueue中 return enqueueMessage(queue, msg, uptimeMillis); }
还有另外一种发送消息的方法,且消息中带有Callback
Handler.post
public final boolean post(@NonNull Runnable r) { return sendMessageDelayed(getPostMessage(r), 0); } // token 即为message携带的数据 public final boolean postAtTime( @NonNull Runnable r, @Nullable Object token, long uptimeMillis) { return sendMessageAtTime(getPostMessage(r, token), uptimeMillis); }
Hand源码中的图片ler.getPosrMessage
private static Message getPostMessage(Runnable r) { // 从消息池中取出一个空白消息 Message m = Message.obtain(); // 给message设置callback m.callback = r; return m; } @UnsupportedAppUsage private static Message getPostMessage(Runnable r, Object token) { Message m = Message.obtain(); // 给message设置obj数据 m.obj = token; m.callback = r; return m; }
Handler.obtainMessage
// 从消息池中取出一个Message使用 public final Message obtainMessage() { return Message.obtain(this); }
Handler.dispatchMessage
// Looper.loopOnce中调用过来的,处理消息 public void dispatchMessage(@NonNull Message msg) { if (msg.callback != null) { // message有callback,直接走callback handleCallback(msg); } else { if (mCallback != null) { // handler有callback,走callback,callback内返回true则直接return,不会执行handlerMessage方法 if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } }
Handler.han变量分为什么变量和什么变量dleMe接口英文ssage
// 由Handler的子类实现,用来处理消息,不实现则不会做任何事,空函数 public void handleMessage(@NonNull Message msg) { }
MessageQueue
源码路径:frameworks/base/core/java/android/os/MessageQueue.java
MessageQueue.enqueueMessage
boolean enqueueMessage(Message msg, long when) { if (msg.target == null) { throw new IllegalArgumentException("Message must have a target."); } synchronized (this) { if (msg.isInUse()) { // inUse 抛出异常 throw new IllegalStateException(msg + " This message is already in use."); } if (mQuitting) { // 表示正在执行结束流程 IllegalStateException e = new IllegalStateException( msg.target + " sending message to a Handler on a dead thread"); Log.w(TAG, e.getMessage(), e); // 回收掉此message,加入message池 msg.recycle(); return false; } msg.markInUse(); msg.when = when; // mMessages 为Message链表,MessageQueue的主要数据结构 Message p = mMessages; // 唤醒标识 boolean needWake; // 三种条件: // 1. MessageQueue中无Message // 2. 消息分发的时间为now // 3. 新消息的发送时间小于链表头部消息的时间 if (p == null || when == 0 || when < p.when) { // 放在链表头 msg.next = p; mMessages = msg; // 需要唤醒MessageQueue.next() needWake = mBlocked; } else { // 链表头不为空,则需要将Message插入到链表中 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; } // 需要唤醒则调用native方法唤醒MessageQueue.next if (needWake) { nativeWake(mPtr); } } return true; }
enqueueM线程撕裂者essa接口卡ge中,新me源码编辑器手机版下载ssage的位置有两种可能:
- 链表头为空、当前message的发送时间变量类型有哪些为0、message的发送时间小于链表头的message发送时间,满足任意一项则将message插入到链表头源码时代部。
- 循环遍历链表,找到链表节点中m变量之间的关系essage的时间大于新message时间的位置 ,将新message插入该位置,找不到则插入到链表尾部。
MessageQueue.next
@UnsupportedAppUsage Message next() { // 此处保存的是native层NativeMessageQueue指针 final long ptr = mPtr; if (ptr == 0) { return null; } int pendingIdleHandlerCount = -1; int nextPollTimeoutMillis = 0; for (;;) { if (nextPollTimeoutMillis != 0) { Binder.flushPendingCommands(); } // 此处调用native方法,会阻塞,第一次调用会一直阻塞(pendingIdleHandlerCount = -1代表一直阻塞) nativePollOnce(ptr, nextPollTimeoutMillis); // 阻塞超时、MessageQueue中有新消息、发生ERROR 时调用以下方法 synchronized (this) { // Try to retrieve the next message. Return if found. final long now = SystemClock.uptimeMillis(); Message prevMsg = null; Message msg = mMessages; 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()); } if (msg != null) { if (now < msg.when) { // MessageQueue中链表头结点的发送时间大于now,需要等待 nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE); } else { // Got a message. mBlocked = false; if (prevMsg != null) { prevMsg.next = msg.next; } else { mMessages = msg.next; } // 取出MessageQueue链表的头节点,给Looper.loopOnce使用 msg.next = null; if (DEBUG) Log.v(TAG, "Returning message: " + msg); msg.markInUse(); return msg; } } else { // No more messages. nextPollTimeoutMillis = -1; } // Process the quit message now that all pending messages have been handled. if (mQuitting) { dispose(); return null; } // 如果MessageQueue中无Message或者链表头Message还没都发送的时间,从mIdleHandlers中获取到idleHandler个数 // mIdleHandlers通过addIdleHandler添加 if (pendingIdleHandlerCount < 0 && (mMessages == null || now < mMessages.when)) { pendingIdleHandlerCount = mIdleHandlers.size(); } if (pendingIdleHandlerCount <= 0) { // No idle handlers to run. Loop and wait some more. mBlocked = true; continue; } if (mPendingIdleHandlers == null) { mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)]; } mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers); } // 从mPendingIdleHandlers取出IdelHandler执行 for (int i = 0; i < pendingIdleHandlerCount; i++) { final IdleHandler idler = mPendingIdleHandlers[i]; mPendingIdleHandlers[i] = null; // release the reference to the handler boolean keep = false; try { // queueIdle返回false,则将当前IdelHandler从mIdleHandlers中彻底移除掉 keep = idler.queueIdle(); } catch (Throwable t) { Log.wtf(TAG, "IdleHandler threw exception", t); } if (!keep) { synchronized (this) { mIdleHandlers.remove(idler); } } } // 将pendingIdleHandlerCount置空 pendingIdleHandlerCount = 0; // 在执行IdelHander的时候,可能MessageQueue中可能已经有消息到来或者原有消息分发时间已到,将等待时间变为0 nextPollTimeoutMillis = 0; } }
当MessageQueue中有消息时,会将消息返回Looper.loopOnce,如没有消息或分发时间未到,则会执行IdelHandler中方法(IdelHandler需要Api调用者通源码过addIdleHander手动add),不会浪费等待源码时代培训怎么样的时间。
MessageQueue.addIdleHandler
public void addIdleHandler(@NonNull IdleHandler handler) { if (handler == null) { throw new NullPointerException("Can't add a null IdleHandler"); } synchronized (this) { mIdleHandlers.add(handler); } }
MessageQueue.removeMessages
void removeMessages(Handler h, int what, Object object) { if (h == null) { return; } synchronized (this) { // Message链表头 Message p = mMessages; // Remove all messages at front. while (p != null && p.target == h && p.what == what && (object == null || p.obj == object)) { Message n = p.next; mMessages = n; p.recycleUnchecked(); p = n; } // Remove all messages after front. while (p != null) { Message n = p.next; if (n != null) { if (n.target == h && n.what == what && (object == null || n.obj == object)) { Message nn = n.next; n.recycleUnchecked(); p.next = nn; continue; } } p = n; } } }
该函数的作用是从MessageQueue中清除条件appointment满足msg.target = h &&变量类型有哪些amp; msg.what = what &&源码之家 (msg.obj == null || msg.ob变量与函数j = object)
的message。
清除的方式也很特别,分为两段进行
- 找到和给定条件相等的mesappearancesage
- 找到则清除掉该msg,并让链表头和指向该节点的next
- 找不到则退出循环
- 从源码编辑器下载上一个循环的位置开始,接着变量的英文遍历链表
- 找到和给定条件相等的msg,清除掉msg
- 找不到接着遍历,直到 p == null
Messa线程和进程的区别是什么geQueue.quit
void quit(boolean safe) { if (!mQuitAllowed) { // mQuitAllowed是构造方法传进来的,为true代表可以终止,为false在此方法内会抛出异常 throw new IllegalStateException("Main thread not allowed to quit."); } synchronized (this) { if (mQuitting) { // 正在 quit,直接 return return; } mQuitting = true; if (safe) { removeAllFutureMessagesLocked(); } else { removeAllMessagesLocked(); } // We can assume mPtr != 0 because mQuitting was previously false. nativeWake(mPtr); } }
quit方法主要线程是什么意思作用是停掉MessageQueue,释放掉MessageQueue中的节点,而释放掉哪些节点是通过参数接口文档safe进行控制的。
当safe为tru线程安全e时,调变量类型有哪些用removeAllFutureMessagesLocked方法,该方法变量内部会判断链表头节点源码之家msg的when
- 当msg.whe接口是什么n > now时,证明链表中的所有节点都没有进行消息分发,可以全部释放
- 当msg.when < now时,变量是什么意思需要遍历链表,找到msg.when > now的节点,从该节点开始进行释放,该节点之前的节点不可以释放,可能该节点之前的节点已经被分发出去了
当safe为false时,调用removeapproachAllMessagesLocked方法,暴力释放掉MessageQueue的所有节点
Message源码之家Queue.removeAllMessag变量名esLocked
private void removeAllMessagesLocked() { Message p = mMessages; while (p != null) { Message n = p.next; p.recycleUnchecked(); p = n; } mMessages = null; }
从链表中移除掉所有message,并且将链表头mMessages置为 null
MessageQueuappeare.removeAllFutureMess变量agesLocked
private void removeAllFutureMessagesLocked() { // 获取当前时间 final long now = SystemClock.uptimeMillis(); // 拿到链表头 Message p = mMessages; if (p != null) { if (p.when > now) { // 链表头的msg发送时间大于当前时间,那链表中所有节点msg的发送时间也一定大于now,具体可以看enqueueMessage方法的实现 // 暴力移除全部节点 removeAllMessagesLocked(); } else { Message n; // 遍历链表,找到msg.when > now的节点 for (;;) { n = p.next; if (n == null) { return; } if (n.when > now) { break; } p = n; } // 断开节点 p.next = null; // 回收掉链表剩余节点 do { p = n; n = p.next; // 回收节点 p.recycleUnchecked(); } while (n != null); } } }
Message
源码路径:frameworks/base/core/ja变量是什么意思va/android/os/Message.java
Filedapple苹果官网
字段 | 含义 |
---|---|
what | 可以看做消息的类型,以此字段标识消息 |
arg1 | 参数1 |
arg2 | 参数2 |
obj | 消息携带的数据 |
whe源码编辑器手机版下载n | 消息送给looper的时间 |
flag | 标识当前Messag源码编辑器手机版下载e的状态,目前有FLAG_IN_USE、FLAG_ASYNCHRONOUS、appearFLAGS_TO_CLEAR_ON_COPY_FROM三种状态 |
next接口英文 | Messapple苹果官网agePo线程数越多越好吗ol中链表节点链接指针 |
调用栈
-------------------------------------------- 向 MessageQueue 发送消息 ----------------------------------------------------- frameworks/base/core/java/android/os/Handler.java | ---> public final boolean sendMessage(@NonNull Message msg) | ---> return sendMessageDelayed(msg, 0); | ---> return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis); | ---> return enqueueMessage(queue, msg, uptimeMillis); | ---> msg.target = this; // 将target指向当前 handler | ---> return queue.enqueueMessage(msg, uptimeMillis); frameworks/base/core/java/android/os/MessageQueue.java | ---> msg.markInUse(); | ---> msg.when = when; | ---> Message p = mMessages; // 拿到链表头 | ---> if (p == null || when == 0 || when < p.when) // 插在链表头部 | ---> msg.next = p; | ---> mMessages = msg; | ---> needWake = mBlocked; | ---> else | ---> for (;;) // 遍历链表,在链表中找到msg合适的插入位置 | ---> msg.next = p; | ---> prev.next = msg; // 插入 | ---> nativeWake(mPtr); // if (needWake) 唤醒等待message的next()方法 ------------------------------------------ Looper 循环从 MessageQueue 中拿到消息并处理 -------------------------------------- frameworks/base/core/java/android/os/Looper.java | ---> public static void loop() | ---> final Looper me = myLooper(); | ---> for (;;) | ---> if (!loopOnce(me, ident, thresholdOverride)) // return; | ---> Message msg = me.mQueue.next(); // 从MessageQueue中拿到message,此处可能会阻塞 frameworks/base/core/java/android/os/MessageQueue.java | ---> for (;;) | ---> nativePollOnce(ptr, nextPollTimeoutMillis); // 可能会阻塞,需要nativeWake唤醒 | ---> Message msg = mMessages; | ---> if (msg != null && msg.target == null) | ---> while (msg != null && !msg.isAsynchronous()); | ---> prevMsg = msg; | ---> msg = msg.next; | ---> if (msg != null) | ---> if (now < msg.when) | ---> nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE); // 计算需要等待的时间 | ---> else | ---> prevMsg.next = msg.next; // if (prevMsg != null) | ---> mMessages = msg.next; // else | ---> msg.next = null; | ---> msg.markInUse(); | ---> return msg; // 返回链表头节点 frameworks/base/core/java/android/os/Looper.java | ---> msg.target.dispatchMessage(msg); // target 指向自实现的 handler frameworks/base/core/java/android/os/Handler.java | ---> if (msg.callback != null) | ---> handleCallback(msg); | ---> message.callback.run(); | ---> else | ---> if (mCallback != null) | ---> if (mCallback.handleMessage(msg)) | ---> return // 上面的mCallback.handleMessage方法如返回true,则不会执行Handler.handleMessage方法 | ---> handleMessage(msg); frameworks/base/core/java/android/os/Looper.java | ---> msg.recycleUnchecked(); // 回收掉message,将该msg加入到message poll
评论(0)