標籤:android 訊息處理機制
劉昊昱
部落格:http://blog.csdn.net/liuhaoyutz
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();50265027 // CloseGuard defaults to true and canbe quite spammy. We5028 // disable it here, but selectivelyenable it later (via5029 // StrictMode) on debug builds, butusing DropBox, not logs.5030 CloseGuard.setEnabled(false);50315032 Environment.initForCurrentUser();50335034 // Set the reporter for event loggingin libcore5035 EventLogger.setReporter(newEventLoggingReporter());50365037 Security.addProvider(newAndroidKeyStoreProvider());50385039 Process.setArgV0("<pre-initialized>");50405041 Looper.prepareMainLooper();50425043 ActivityThread thread = newActivityThread();5044 thread.attach(false);50455046 if (sMainThreadHandler == null) {5047 sMainThreadHandler =thread.getHandler();5048 }50495050 AsyncTask.init();50515052 if (false) {5053 Looper.myLooper().setMessageLogging(new5054 LogPrinter(Log.DEBUG,"ActivityThread"));5055 }5056 if(!"user".equals(android.os.Build.TYPE)) {5057 sLocalLog = new LocalLog(128);5058 Looper.myLooper().setMessageLogging(sLocalLog);5059 }50605061 Looper.loop();50625063 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。