Android架構分析之Android訊息處理機制(三)
作者:劉昊昱
Android版本:4.4.2
本文我們來分析AndroidUI執行緒即主執行緒是怎樣實現對訊息的處理的。
UI執行緒的實現類定義在frameworks/base/core/java/android/app/ActivityThread.java檔案中。我們來看Android對ActivityThread類的說明 :
130/**
131 * This manages the execution of the mainthread in an
132 * application process, scheduling andexecuting activities,
133 * broadcasts, and other operations on itas the activity
134 * manager requests.
135 *
136 * {@hide}
137 */
下面是ActivityThread類的main函式:
5024 public static void main(String[] args) { 5025 SamplingProfilerIntegration.start(); 5026 5027 // CloseGuard defaults to true and canbe quite spammy. We 5028 // disable it here, but selectivelyenable it later (via 5029 // StrictMode) on debug builds, butusing DropBox, not logs. 5030 CloseGuard.setEnabled(false); 5031 5032 Environment.initForCurrentUser(); 5033 5034 // Set the reporter for event loggingin libcore 5035 EventLogger.setReporter(newEventLoggingReporter()); 5036 5037 Security.addProvider(newAndroidKeyStoreProvider()); 5038 5039 Process.setArgV0("<pre-initialized>"); 5040 5041 Looper.prepareMainLooper(); 5042 5043 ActivityThread thread = newActivityThread(); 5044 thread.attach(false); 5045 5046 if (sMainThreadHandler == null) { 5047 sMainThreadHandler =thread.getHandler(); 5048 } 5049 5050 AsyncTask.init(); 5051 5052 if (false) { 5053 Looper.myLooper().setMessageLogging(new 5054 LogPrinter(Log.DEBUG,"ActivityThread")); 5055 } 5056 if(!"user".equals(android.os.Build.TYPE)) { 5057 sLocalLog = new LocalLog(128); 5058 Looper.myLooper().setMessageLogging(sLocalLog); 5059 } 5060 5061 Looper.loop(); 5062 5063 throw new RuntimeException("Mainthread loop unexpectedly exited"); 5064 }
5041行,呼叫Looper.prepareMainLooper函式,這與上一篇文章中介紹的普通執行緒呼叫Looper.prepare()函式不同,我們來看Looper.prepareMainLooper函式的實現:
88 /** 89 *Initialize the current thread as a looper, marking it as an 90 *application's main looper. The main looper for your application 91 *is created by the Android environment, so you should never need 92 *to call this function yourself. Seealso: {@link #prepare()} 93 */ 94 public static void prepareMainLooper() { 95 prepare(false); 96 synchronized (Looper.class) { 97 if (sMainLooper != null) { 98 throw newIllegalStateException("The main Looper has already been prepared."); 99 } 100 sMainLooper = myLooper(); 101 } 102 }
可以看到,95行,prepareMainLooper首先呼叫prepare(false),所以和普通執行緒類似,只不過傳遞的引數是false,表示該Looper不能退出,因為UI執行緒是不允許退出訊息迴圈的。
100行,呼叫myLooper函式,取得當前Looper即UI執行緒Looper,儲存在sMainLooper變數中,這樣做的目的是,如果其它執行緒想要獲得UI執行緒Looper,只需要呼叫getMainLooper函式即可。
5046-5048行,如果sMainThreadHandler為null,呼叫thread.getHandler(),該函式返回一個H類物件mH,H類ActivityThread類的內部類,繼承自Handler類,其中完成了對許多Message的預設處理。
5061行,呼叫Looper.loop()函式,進入訊息迴圈處理。
對比上一篇文章《Android架構分析之Android訊息處理機制(二)》,分析到這裡,我們就可以看到UI執行緒與普通執行緒執行訊息處理的流程大致相同,區別僅是呼叫Looper.prepareMainLooper,而不是Looper.prepare,同時Handler使用的是H類物件mH。