以下源码采用api19
Activity的启动是受AMS(ActivityMessageService),但是直观来讲,很多童鞋并不熟悉AMS,反而对ActivityThread更加熟悉;其实我们的android系统很像一个BS的架构,Liunx驱动以及底层是服务端,应用层是客户端;服务端和客户端通过Binder来通信;
今天我先讲讲客户端,从ActivityThread讲起,当然ActivityThread其实是在AMS通过反射调用加载到虚拟机中的,这篇先不讲,先将ActivityThread启动后和AMS进行交互的过程。
ActivityThread通过它的内部类ApplicationThread,它其实是个BInder,与Ams交互,接受Ams的指令;
ActivityThread启动后,会从mian()函数开始执行,下面我们基本上就分析main函数。
一、为主线程创建一个Looper对象
在main函数中,会调用prepareMainLooper()为UI线程创建一个Looper对象,实际上prepareMainLooper函数是调用prepare(boolean quitAllowed)函数来为当前线程创建Lopper对象的。这里可以进入Looper去看看源码。
在prepare()函数中,会new一个Looper对象,通过ThreadLocalde的set()方法将新创建的Looper对象保存进去,然后可以通过ThreadLocal的get方法来获取当前线程的Looper对象,比如prepareMainLooper中的,sMainLooper = myLooper();实际上myLooper()方法中是通过sThreadLocal.get()来获取当前线程的looper对象的;
前面说了在sThreadLocal.set(new Looper(quitAllowed))的时候会创建一个Looper对象,在创建Looper对象的时候,会初始化一个MessageQueue对象。Looper对象到这里初始化完毕,但是并未进入消息循环,直到下面调用Looper.loop();
源码:
public static void main(String[] args) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
SamplingProfilerIntegration.start();
// CloseGuard defaults to true and can be quite spammy. We
// disable it here, but selectively enable it later (via
// StrictMode) on debug builds, but using DropBox, not logs.
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
// Set the reporter for event logging in libcore
EventLogger.setReporter(new EventLoggingReporter());
AndroidKeyStoreProvider.install();
// Make sure TrustedCertificateStore looks in the right place for CA certificates
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
Process.setArgV0("<pre-initialized>");
//(1)为主线程创建一个Looper对象
Looper.prepareMainLooper();
//(2)创建ActivityThread对象
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
// End of event ActivityThreadMain.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
/**
* 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. See also: {@link #prepare()}
*/
public static void prepareMainLooper() {
prepare(false);
synchronized (Looper.class) {
if (sMainLooper != null) {
throw new IllegalStateException("The main Looper has already been prepared.");
}
sMainLooper = myLooper();
}
}
/**
* Return the Looper object associated with the current thread. Returns
* null if the calling thread is not associated with a Looper.
*/
public static Looper myLooper() {
return sThreadLocal.get();
}
private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(quitAllowed));
}
Looper的构造函数,初始化Looper的时候会创建MessageQueue,和获取当前的线程对象;
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
ThreadLocal:可以看源码中的解释,其实的功能很特殊,可以是不同的线程持有同一个对象,但是不同的线程中该对象具有不同的属性值,比如 有ThreadA,ThreadB,ThreadC共同持有 int objectA;在ABC三个线程中分别赋值:1,2,3,那么会有这种的现象,虽然是同一个引用,但是三个线程中的值各不相同,并且三个线程修改的值也只有在自己的线程才会有效
/**
* Implements a thread-local storage, that is, a variable for which each thread
* has its own value. All threads share the same {@code ThreadLocal} object,
* but each sees a different value when accessing it, and changes made by one
* thread do not affect the other threads. The implementation supports
* {@code null} values.
*
* @see java.lang.Thread
* @author Bob Lee
*/
public class ThreadLocal<T> {
二、创建ActivityThread对象
上面讲完了Looper.prepareMainLooper();接下会创建一个ActivityThread对象
见上面源码(2),