Activity的启动过程(1)

本文详细剖析了Android中Activity的启动过程,从ActivityThread的main函数开始,讲解了Looper和MessageQueue的创建,再到ApplicationThread与AMS的交互,重点阐述了Activity如何通过IPC与AMS建立联系,并初始化Application。此外,还涵盖了UI线程进入消息循环,以及Activity和View的初始化步骤。
摘要由CSDN通过智能技术生成

 

以下源码采用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),

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值