How do I communicate with child threads through Handler?
Handler mechanism
Let’s look at how the main thread of android source code communicates with other threads:
public static void main(String[] args) {
// Prepare the message circulator for the main thread
Looper.prepareMainLooper();
// The main thread is bound to Application
ActivityThread thread = new ActivityThread();
thread.attach(false);
// Get the message handler mH for the main thread
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
// Loop out the message
Looper.loop();
}
Copy the code
1, which
Get the Looper of the current main thread:
Looper.prepareMainLooper();
Copy the code
The created Looper is stored using ThreadLocal, with each thread having a unique 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));
}
Copy the code
When Looper is created, the current thread is bound and a message queue is created to store messages sent by other threads:
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
Copy the code
Get the Looper of the current thread:
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
Copy the code
2, the Handler
Handler Handler Handler Handler Handler Handler Handler Handler Handler Handler Handler Handler Handler
public Handler(@NonNull Looper looper) {
this(looper, null, false);
}
Copy the code
After creating the Handler, we need to use Looper to loop out MessageQueue’s Message:
Looper.loop();
Copy the code
Once a Message is retrieved, the corresponding Message Handler distributes the Message:
msg.target.dispatchMessage(msg);
Copy the code
3, the Message
Handler sends a Message:
public final boolean sendMessage(@NonNull Message msg) {
return sendMessageDelayed(msg, 0);
}
Copy the code
Message binding 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);
}
Copy the code
Insert Message into MessageQueue, wait to be fetched by Looper and then distributed by Handler:
queue.enqueueMessage(msg, uptimeMillis)
Copy the code
The flow chart
The following is a flow chart of the Handler message mechanism drawn by the author according to the source code:
Message communication between child threads
Finally, we follow the example and carry out communication between sub-threads:
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(a) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Message message = new Message();
message.obj = "Message From A.";
// Send a messagesHandler.sendMessage(message); }},"A").start();
new Thread(new Runnable() {
@Override
public void run(a) {
// Create Looper and MessageQueue
Looper.prepare();
/ / create a Handler
sHandler = new Handler(Looper.myLooper()) {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
// Process the message
System.out.println("Message To B:"+ msg.obj); }};/ / which cyclesLooper.loop(); }},"B").start(); }}Copy the code
Welcome to pay attention to the Android technology stack, focus on Android technology learning public number, dedicated to improving the Android developers professional skills!