1. 程式人生 > >Android架構分析之Android訊息處理機制(三)

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。