源码基于 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