如何通过Handler进行子线程间的通信?

Handler机制

首先来看android源码的主线程是如何与其他线程进行通信的:

public static void main(String[] args) {
//准备好主线程的消息循环器
Looper.prepareMainLooper();

//主线程,绑定到Application中去
ActivityThread thread = new ActivityThread();
thread.attach(false);

//获取主线程的消息处理器mH
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}

//循环取出消息
Looper.loop();
}

1、Looper

先获取当前主线程的Looper:

Looper.prepareMainLooper();

创建后的Looper会使用ThreadLocal存储起来,每个线程都有对应的唯一的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:

public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}

2、Handler

获取Looper后,就可以根据Looper创建对应的Handler,表示使用当前Handler来处理Looper取出来的Message:

public Handler(@NonNull Looper looper) {
this(looper, null, false);
}

创建Handler后就需要使用Looper去循环取出MessageQueue的Message:

Looper.loop();

一旦获取到Message,Message对应的Handler就会把Message分发出去:

msg.target.dispatchMessage(msg);

3、Message

Handler发送Message:

public final boolean sendMessage(@NonNull Message msg) {
return sendMessageDelayed(msg, 0);
}

Message绑定Handler:

private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,
long uptimeMillis) {
msg.target = this;
msg.workSourceUid = ThreadLocalWorkSource.getUid();

if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}

将Message插入消息队列MessageQueue,等待被Looper取出然后被Handler分发出去:

queue.enqueueMessage(msg, uptimeMillis)

流程图

下图是笔者根据源码画出的Handler消息机制的流程图:

使用Handler机制进行子线程间的消息通信_Android

子线程间的消息通信

最后我们依样画葫芦,进行子线程间的通信:

public class HandlerActivity extends AppCompatActivity {

private static Handler sHandler;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Message message = new Message();
message.obj = "Message From A.";
//发送消息
sHandler.sendMessage(message);
}
}, "A").start();

new Thread(new Runnable() {
@Override
public void run() {
//创建Looper和MessageQueue
Looper.prepare();
//创建Handler
sHandler = new Handler(Looper.myLooper()) {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
//处理消息
System.out.println("Message To B:" + msg.obj);
}
};
//循环Looper
Looper.loop();
}
}, "B").start();
}
}

欢迎关注Android技术堆栈,专注于Android技术学习的公众号,致力于提高Android开发者们的专业技能!

使用Handler机制进行子线程间的消息通信_流程图_02