Android應用程序消息處理機制(Looper、Handler)分析(2)
在Android應用程序進程啟動過程的源代碼分析一文中,我們分析了Android應用程序進程的啟動過程。
Android應用程序進程在啟動的時候, 會在進程中加載ActivityThread類,并且執(zhí)行這個類的main函數。
應用程序的消息循環(huán)過程就是在這個main函數里面實現的。
我們來看看這個函數的實現,它定義在frameworks/base/core/java/android/app/ActivityThread.java文件中:
- [java] view plaincopypublic final class ActivityThread {
- ......
- public static final void main(String[] args) {
- ......
- Looper.prepareMainLooper();
- ......
- ActivityThread thread = new ActivityThread();
- thread.attach(false);
- ......
- Looper.loop();
- ......
- thread.detach();
- ......
- }
- }
這個函數做了兩件事情,一是在主線程中創(chuàng)建了一個ActivityThread實例,二是通過Looper類使主線程進入消息循環(huán)中,這里我們只關注后者。
首先看Looper.prepareMainLooper函數的實現,這是一個靜態(tài)成員函數,定義在frameworks/base/core/java/android/os/Looper.java文件中:
- [java] view plaincopypublic class Looper {
- ......
- private static final ThreadLocal sThreadLocal = new ThreadLocal();
- final MessageQueue mQueue;
- ......
- /** Initialize the current thread as a looper.
- * This gives you a chance to create handlers that then reference
- * this looper, before actually starting the loop. Be sure to call
- * {@link #loop()} after calling this method, and end it by calling
- * {@link #quit()}.
- */
- public static final void prepare() {
- if (sThreadLocal.get() != null) {
- throw new RuntimeException("Only one Looper may be created per
- thread");
- }
- sThreadLocal.set(new Looper());
- }
- /** Initialize the current thread as a looper, marking it as an
- application's main
- * looper. The main looper for your application is created by the Android
- environment,
- * so you should never need to call this function yourself.
- * {@link #prepare()}
- */
- public static final void prepareMainLooper() {
- prepare();
- setMainLooper(myLooper());
- if (Process.supportsProcesses()) {
- myLooper().mQueue.mQuitAllowed = false;
- }
- }
- private synchronized static void setMainLooper(Looper looper) {
- mMainLooper = looper;
- }
- /**
- * Return the Looper object associated with the current thread. Returns
- * null if the calling thread is not associated with a Looper.
- */
- public static final Looper myLooper() {
- return (Looper)sThreadLocal.get();
- }
- private Looper() {
- mQueue = new MessageQueue();
- mRun = true;
- mThread = Thread.currentThread();
- }
- ......
- }