1. 主线程消息循环概述
Android 的主线程就是运行 ActivityThread 的线程(由 Zygote fork 出来的进程),主线程的入口方法为
main()
方法在
main()
方法中系统会通过Looper.prepareMainLooper()
方法来创建主线程的 Looper 以及 MesssageQueue,并通过Looper.loop()
方法来开启主线程的消息循环。main()
方法源码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24// ActivityThread.java
public static void main(String[] args) {
// bla bla bla
Looper.prepareMainLooper();
// bla bla bla
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
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");
}1
2
3
4
5
6// AcrivityThread.java
final H mH = new H();
final Handler getHandler() {
return mH;
}主线程的消息循环开始了以后,ActivityThread 还需要一个 Handler 来和消息队列进行交互,这个 Handler 就是其内部类 ActivityThread.H,它内部定义了一组消息类型,主要包含了四大组件的启动和停止等过程。类 H 源码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102private class H extends Handler {
// bla bla bla
public static final int LAUNCH_ACTIVITY = 100;
public static final int PAUSE_ACTIVITY = 101;
public static final int PAUSE_ACTIVITY_FINISHING = 102;
public static final int STOP_ACTIVITY_SHOW = 103;
public static final int STOP_ACTIVITY_HIDE = 104;
public static final int SHOW_WINDOW = 105;
public static final int HIDE_WINDOW = 106;
public static final int RESUME_ACTIVITY = 107;
public static final int SEND_RESULT = 108;
public static final int DESTROY_ACTIVITY = 109;
public static final int BIND_APPLICATION = 110;
public static final int EXIT_APPLICATION = 111;
public static final int NEW_INTENT = 112;
public static final int RECEIVER = 113;
public static final int CREATE_SERVICE = 114;
public static final int SERVICE_ARGS = 115;
public static final int STOP_SERVICE = 116;
// bla bla bla
public void handleMessage(Message msg) {
if (DEBUG_MESSAGE) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case BIND_APPLICATION:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case EXIT_APPLICATION:
if (mInitialApplication != null) {
mInitialApplication.onTerminate();
}
Looer.myLooper().quit();
break;
case RECEIVER:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiverCom");
handleReceiver((ReceiverData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case CREATE_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
handleCreateService((CreateServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case BIND_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
handleBindService((BindServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case UNBIND_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind");
handleUnbindService((BindServiceData)msg.obj);
schedulePurgeIdler();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case STOP_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop");
handleStopService((IBinder)msg.obj);
schedulePurgeIdler();
Trace.traceEnd(Trace。TRACE_TAG_ACTIVITY_MANAGER);
break;
...
case APPLICATION_INFO_CHANGED:
mUpdatingSystemConfig = true;
try {
handleApplicationInfoChanged((Application)msg.obj);
} finally {
mUpdatingSystemConfig = false;
}
break;
case RUN_ISOLATED_ENTRY_POINT:
handleRunIsolatedEntryPoint((String) ((SomeArgs)msg.obj).arg1), (String[])((SomeArgs)msg.obj).arg2);
break;
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);
if (isSystem()) {
// Client transactions inside system process are recycled on the client side
// instead of ClientLifecycleManager to avoid being cleared before this
// message is handled.
transaction.recycle();
}
// TODO(lifecycle): Recycle locally scheduled transactions.
break;
case RELAUNCH_ACTIVITY:
handleRelaunchActivityLocally((IBinder)msg.obj);
break;
case PURGE_RESOURCES:
schedulePurgeIdler();
break;
}
Object obj = msg.obj;
if (obj instanceof SomeArgs) {
((SomeArgs)obj).recycle;
}
if (DEBUG_MESSAGE) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
}
}- ActivityThread 通过 ApplicationThread 和 AMS 进行 IPC 进程间通信
- AMS 以进程间通信的方式完成 ActivityThread 的请求后会回调 ApplicationThread 中的 Binder 方法
- 然后 ApplicationThread 会向 H 发送消息,H 收到消息后会将 ApplicationThread 中的逻辑切换到 ActivityThread 中去执行,即切换到主线程中去执行
- Activity 的生命周期都是依靠主线程的
Looper.loop()
,这个过程就是主线程的消息循环模型 - 主线程 Looper 的退出机制:
- 在 App 退出时,ActivityThread 中的 mH(Handler)收到消息:
case EXIT_APPLICATION:
,执行退出操作:Looper.myLooper().quit();
- 如果手动退出主线程 Looper,最终 MessageQueue 的
quit()
方法会抛出异常:throw new IllegalStateException("Main thread not allowed to quit.");
- 正常情况下,主线程不允许退出,一旦退出就意味着程序挂了,即使退出也不应该用手动调主线程 Looper 的
quit()
方法的方式
- 在 App 退出时,ActivityThread 中的 mH(Handler)收到消息: