SoFunction
Updated on 2025-04-07

Android development

When do you need a Looper

Looper is used to encapsulate message loops in android threads. By default, a thread does not have a message loop. You need to call () to create a message loop for the thread, call () to make the message loop work, and create a message queue using () and () to allow message processing to be completed in the thread.

What to pay attention to when using Looper

The code written after () will not be executed immediately. When ().quit() is called, the loop will abort and the subsequent code will be run. The Looper object stores messages and events through MessageQueue. A thread can only have one Looper, corresponding to one MessageQueue.

For example, the following code will only be executed after gettingLooper().quit() is called.

class LooperThread extends Thread
{
4 public void run() 
{
();
//Code 1....();
//Code 2....} 
}

Beware of memory leakage caused by thread failure; for example, if you associate a Thread with a life cycle exceeding the Activity, remember to end the thread when exiting the Activity. A typical example is that the run method of HandlerThread is a dead loop, which will not end on its own. The life cycle of the thread exceeds the life cycle of the Activity. We must manually transfer().quit(); in the Activity destroy method to not leak.

Looper and Activity

The MainUI thread of the Activity has a message queue by default. Therefore, when creating a new Handler in the Activity, there is no need to call () first

Why does the () in the main thread not cause ANR

It is a class for the main thread entry. Here you can see the common main method in writing Java programs, and the main method is the entrance to the entire Java program.

ActivityThread source code

public static final void main(String[] args) {
...
//Create Looper and MessageQueue();
...
//The poller starts polling();
...
}

()method

while (true) {
//Fetching out the message queue may blockMessage msg = (); // might block
...
//Parse the message and distribute the message(msg);
...
}

The main method of ActivityThread is mainly to make a message loop. Once the message loop is exited, your application will also exit. Then why doesn't this dead loop cause ANR exceptions?

Because Android is driven by events, () continuously receives and processes events. Every click touch or activity's life cycle runs under the control of (). If it stops, the application will stop. It can only be a certain message or processing of the message blocks (), rather than () blocking it. In other words, our code is actually executed in this loop, and of course it will not block.

Part of the source code of handleMessage method

public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) (TAG, ">>> handling: " + codeToString());
switch () {
case LAUNCH_ACTIVITY: {
(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
final ActivityClientRecord r = (ActivityClientRecord) ;
 = getPackageInfoNoCheck(, );
handleLaunchActivity(r, null);
(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
break;
case RELAUNCH_ACTIVITY: {
(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
ActivityClientRecord r = (ActivityClientRecord) ;
handleRelaunchActivity(r);
(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
break;
case PAUSE_ACTIVITY:
(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
handlePauseActivity((IBinder) , false, (msg.arg1 & 1) != 0, msg.arg2, (msg.arg1 & 2) != 0);
maybeSnapshot();
(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case PAUSE_ACTIVITY_FINISHING:
(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
handlePauseActivity((IBinder) , true, (msg.arg1 & 1) != 0, msg.arg2, (msg.arg1 & 1) != 0);
(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
...........
}
}

It can be seen that the life cycle of the activity depends on the main thread, and corresponding measures are taken when different messages are received.

If a message is processed for too long, for example, if you process time-consuming operations in onCreate() and onResume(), then the next message, such as the user's click event, cannot be processed, and the entire loop will be stuttered, and over time it becomes ANR.