作者:刘昊昱
博客: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(); 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。