“This is the 16th day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021.”
In the previous article we introduced child threads that send messages to the main thread.
The main thread sends messages to child threads
new Thread(new Runnable(){
@Override
public void run(a) {
Looper.prepare();
handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
// Process the message
switch (msg.what) {
case 1:
Log.d(TAG, "Received message:"+msg.obj);
break;
default:
break; }}}; Looper.loop(); } }).start(); Button button=findViewById(R.id.bt); button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Message msg = Message.obtain();
msg.what = 1;
msg.obj = "Message from master thread";
// Send messages to child threadshandler.sendMessage(msg); }});Copy the code
The main difference is that looper.prepare () is called before the Handler is created in the child thread and looper.loop () is called after it. But why don’t you do that in the main thread? In the system main thread the system is already created.
public static void main(String[] args) {
/ /...
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
Looper.loop();
}
Copy the code
The Looper created in the main thread is in the ActivityThread.main method, which is the entry point to the App.
- PrepareMainLooper (), which is actually called Looper. Loop, initialize Looper, MessageQueue, etc.
- The member variable Handler mH is initialized when the ActivityThread is created.
- Assign the member variable mH to sMainThreadHandler
- Finally, looper.loop () is called to start an endless loop, and messages are extracted from MessageQueue for processing.
This is how Looper is created in the main thread.
Principles of Handler mechanism
The Handler mechanism is mainly designed in four parts: Message, Hanlde, Looper, and Message queue.
1.Looper
First, understand its construction method.
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
Copy the code
The MessageQueue object is initialized when Looper is created. The most important methods are prepare() and loop(), which are analyzed respectively in the following sections.
prepare()
Prepare ()->prepare(true)
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
private static Looper sMainLooper; // guarded by Looper.class
private static void prepare(boolean quitAllowed) {
if(sThreadLocal.get() ! =null) {
// a thread creates a looper object
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(quitAllowed));
}
Copy the code
ThreadLocal is an internal data store class that stores data in a specified thread. Once the data is stored, only the specified thread can retrieve the stored data. Other threads cannot retrieve the data. This ensures that each thread has one Looper, and the source code also shows that a thread can only have one Looper, otherwise an exception will be thrown.
loop()
More on that later.