Android启动原理剖析

我们知道Android是以一个Activity为单位的,但是我们并没有看到一个Activity是怎么开始启动的。今天我 们就从Android的源代码开始讲吧。

ActivityThread:

Android的一个apk在打开时,使用到的第一个类就是这个类。我们先来说这个类。等说完这个类就能了解Android应用程序的启动原理了。这货名字取名有一个Thread结尾,貌似是一个线程类。其实他并不是一个线程类,这个类没有继承任何类。或者说是直接继承在Object类。我们来看ActivityThread源码:

public final class ActivityThread {
    ....
}

这是ActivityThread定义时候的的源码,可以看出他根本没有继承任何类。那他为什么要以Thread来结尾的。貌似很不合理。其实不然。想必大家应该Android的异步线程机制吧。其实ActivityThread在创建的时候同时也启动了一个线程,这个线程就是一个异步线程,他创建出了MessageQueue,并同时进行消息的轮询,因此当这个应用程序在运行时,这个线程是一直都在的。这个线程就是应用程序的主线程,UI的处理等都是在这个线程处理的。
在AcitivityThread这个类的是有一个main方法的。我们知道java应用程序的入口就是main方法。这就是程序的入口。我们来看ActivityThread的源代码:

    public static void main(String[] args) {
        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());
        Security.addProvider(new AndroidKeyStoreProvider());
        Process.setArgV0("<pre-initialized>");
       //关键部分,看这里
        Looper.prepareMainLooper();
        ActivityThread thread = new ActivityThread();
        thread.attach(false);
        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }
        AsyncTask.init();
        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

其他的部分我们先不要管,先看关键部分,就是我注释的那个地方。在这里先是使用Looper.prepareMainLooper();方法来创建一个MessageQueue实例。prepareMainLooper内部会调用prepare()方法创建消息队列(MessageQueue)。创建出来之后,就会创建一个ActivityThread对象。这个ActivityThread对象内部会创建出一个Handler和一个ApplicationThread对象,其中这两个对象稍后会介绍,(这里应该有一个中断向量,或者然后再启一个线程去讲解Handler对象和Application对象,哈哈)先压一压。在创建出这个ActivityThread对象之后。中间部分略过不表。之后这里会调用Looper.loop(),是消息队里进行循环。所以说这个ActivityThread是一直都在的,因为需要一直等待取其他线程发过来的消息。这个线程就是我们的主线程。Activity,Service等的管理都是在这里。之后会介绍。
好了,这个过程想必大家都了解了,现在我们说一说我们的Handler和ApplicationThread。在ActivityThread中的这个Handler其实是一个内部类,类名是H,对,就是H一个字母,他是继承自Handler对象的。我们来看一下源代码:
技术分享
在第3行,在这里我们可以看到,他创建了一个H类的实例。注意,这里是类的成员变量区域,不是在某个方法里面。意思就是这个类在创建的同时,这个mH对象就创建出来了。所以说这个mH相当于是主线程的,也就是在main里创建出来的。而这个对象是用于其他线程想主线程发消息的。我们再来看看main函数中我们没有提到的那部分:

      Looper.prepareMainLooper();
        ActivityThread thread = new ActivityThread();
        thread.attach(false);
        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }
        AsyncTa

我们在if语句里面可以看到这样一个语句sMainThreadHandler = thread.getHandler();thread是刚刚创建出来的ActivityThread实例,而getHandler方法返回的正是mH实例。
接下来说一下ApplicationThread这个类,该类是ActivityThread的内部类,该类的作用是什么呢。其实这里涉及到了进程间的通信,这个类是负责接收远程的AmS(ActivitymanagerService)IPC(进程间通信)调用的。而这个的调用一般是Android系统去调用的,这个相当于一种进程间通信,Android系统会有一个服务,用于监控用户的操作等,当用户进行相关操作是会通过进程之间的通信去通知这个应用程序做相应的反应,比如启动一个Activity。当这个类收到通知之后,接下来就会安排Activity的启动,我们可以看一下这个类的源代码:
技术分享
这里贴出其中的部分代码,注意不是这个类的全部代码,只是其中的一部分。我们看一下其中的第二个方法
schedulePauseActivity该方法的意思应该是“安排暂停activity”,该方法就是让Activity调用onPause的代码。下面的其他代码也都是类似的。都是管理service和activity的代码,在这些方法的内部都会调用sendMessage,而这个方法的内部又会继续调用mh.sendMessage()。将暂停或者启动Activity的相关消息安排到主线程的MessageQueue队列中,等待消息队列轮询来处理该消息。我们可以从这些方法的名字也能看出来,schedule是安排的意思,“安排暂停activity”就表示你把“暂停activity”这件事安排一下,等MessageQueue手头的事忙完,再来处理“暂停activity”的事。而安排这件事的人是谁呢,就是mH这个助理了,由他把消息发送给MessageQueue。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。