After analyzing the Handler's construction method, we know that if we do not pass in the Looper object, we will use the Looper of this thread. This also explains the need to call Looper.prepare() in non UI threads first, because the Looper object is created there and saved in sThreadLocal; then the problem comes:
Where is the Looper assigned to the Handler initialized in the UI thread?
Main method in main thread ActivityThread
public static void main(String[] args) {
//Code unrelated to this article
...
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
// End of event ActivityThreadMain.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
Looper.prepareMainLooper() method
public static void prepareMainLooper() {
//Equivalent to Looper.prepare()
prepare(false);
synchronized (Looper.class) {
if (sMainLooper != null) {
throw new IllegalStateException("The main Looper has already been prepared.");
}
sMainLooper = myLooper();
}
//============================
public static Looper getMainLooper() {
synchronized (Looper.class) {
return sMainLooper;
}
}
Create handler
final Handler getHandler() {
return mH;
}
//========================================================
final H mH = new H();
//===================================================
private class H extends Handler {
...
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
//There are many other case s
...
}
}
}
This H is mainly responsible for the application of Activity, Broadcast and so on.