[android原始碼日記]-android的主執行緒為什麼不會因為Looper.loop()裡面的死迴圈卡死?
阿新 • • 發佈:2018-12-14
一下是按照我自己的理解做的一個記錄。
顯而易見,在我們提出這個問題的時候,我們知道安卓主執行緒(又叫UI執行緒)在應用程式啟動ActivityThread的時候,就依次呼叫 Looper.prepareMainLooper(); Looper.loop();了,實際上跟我們在工作執行緒中使用Looper.prepare();Looper.loop();
ActivityThread main函式原始碼:
public static void main(String[] args) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain" );
SamplingProfilerIntegration.start();
// CloseGuard defaults to true and can be quite spammy. We
// disable it here, but selectively enable it later (via
// StrictMode) on debug builds, but using DropBox, not logs.
CloseGuard.setEnabled(false);
Environment.initForCurrentUser() ;
// Set the reporter for event logging in libcore
EventLogger.setReporter(new EventLoggingReporter());
// Make sure TrustedCertificateStore looks in the right place for CA certificates
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore. setDefaultUserDirectory(configDir);
Process.setArgV0("<pre-initialized>");
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.loop()裡面是個死迴圈啊,既然主執行緒在這裡就進入了死迴圈了那後面的android生命週期還怎麼執行?
android中的主執行緒確實不會因為looper.loop()裡面的死迴圈卡死,執行緒本質上只是一段可執行的程式碼,而這串程式碼結束之後,執行緒的生命也就結束了,而android中的Looper.loop()的作用正是為了不讓主執行緒終止,從而一直執行,而它的方式正是啟動一個死迴圈。
public static void loop() {
final Looper me = myLooper();
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
final MessageQueue queue = me.mQueue;
// Make sure the identity of this thread is that of the local process,
// and keep track of what that identity token actually is.
Binder.clearCallingIdentity();
final long ident = Binder.clearCallingIdentity();
for (;;) {
Message msg = queue.next();
....
}
}
那麼在進入死迴圈之後,又是怎麼去處理諸如點選,滑動,這些事務的呢?
那就是通過啟動一個新的執行緒來處理的:
事實上,在ActivityThread main函式中,thread.attach(false);這一行就是啟動了一個新執行緒。
public static void main(String[] args) {
....
//建立Looper和MessageQueue物件,用於處理主執行緒的訊息
Looper.prepareMainLooper();
//建立ActivityThread物件
ActivityThread thread = new ActivityThread();
//建立Binder通道 (建立新執行緒)
thread.attach(false);
Looper.loop(); //訊息迴圈執行
throw new RuntimeException("Main thread loop unexpectedly exited");
}
但我看ActivityThread沒有繼承Thread啊,他不是個執行緒啊,,這個地方還不明白,先做筆記。。等看明白了回來補。