Activity的启动分为两种:

根Activity的启动

按下桌面的程序快捷图标,启动应用程序的第一个Activity的过程,因此根Activity的启动过程也可以理解为应用程序的启动过程。

普通Activity的启动

程序内从一个Activity打开另外一个Activity的过程的启动。

Android优先启动activity android activity启动流程详解_java

 

Activity大体启动流程

主要涉及四个进程:

  1. Launcher进程,也就是桌面进程
  2. 系统服务进程,AMS所在进程
  3. Zygote进程,负责创建进程
  4. 应用程序进程,也就是即将要启动的进程

主要流程:

  1. Launcher进程请求AMS创建activity
  2. AMS请求Zygote创建进程。
  3. Zygote通过fork自己来创建进程。并通知AMS创建完成。
  4. AMS通知应用进程创建根Activity。

解释:

    在Android系统中,zygote是一个native进程,是Android系统上所有应用进程的父进程,我们系统上app的进程都是由这个zygote分裂出来的。zygote则是由Linux系统用户空间的第一个进程——init进程,通过fork的方式创建的。 

根Activity启动过程总体可以分为如下三步

  1. Launcher请求AMS的过程
  2. AMS到ApplicationThread的调用过程
  3. ActivityThread启动Activity

第一步:Launcher(安卓系统桌面启动器)请求AMS(ActivityManagerService)的过程 

解释:

    Launcher是安卓系统中的桌面启动器,安卓系统的桌面UI统称为Launcher。Launcher是安卓系统中的主要程序组件之一,安卓系统中如果没有Launcher就无法启动安卓桌面。

    AMS是Android中最核心的服务,主要负责系统中四大组件的启动、切换、调度及应用进程的管理和调度等工作,其职责与操作系统中的进程管理和调度模块相类似,因此它在Android中非常重要。

    Launcher是Android系统的第一个应用程序,它会读取 PakgesManagerService 来获取当前系统装了哪些应用,并把这些应用程序的快捷图标展示在桌面上。我们通过点击应用的快捷图标,就会通过Launcher请求AMS来启动该应用。

Android优先启动activity android activity启动流程详解_应用程序_02

startActivitySafely()

// launcher3/Launcher.java
public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
        ...
        // 1 设置标志singleTask,意味着在新的栈打开
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        if (v != null) {
            intent.setSourceBounds(getViewBounds(v));
        }
        try {
            if (Utilities.ATLEAST_MARSHMALLOW
                    && (item instanceof ShortcutInfo)
                    && (item.itemType == Favorites.ITEM_TYPE_SHORTCUT
                     || item.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT)
                    && !((ShortcutInfo) item).isPromise()) {
                // Shortcuts need some special checks due to legacy reasons.
                startShortcutIntentSafely(intent, optsBundle, item);
            } else if (user == null || user.equals(Process.myUserHandle())) {
                // 2 
                startActivity(intent, optsBundle);
            } 
            ...
        } catch (ActivityNotFoundException|SecurityException e) {
          ...
        }
        return false;
    }

注释1:创建一个intent后把intent的Flag置为 FLAG_ACTIVITY_NEW_TASK,这个flag表示这个Activity会在新的任务栈中启动。

一般来说,往下走,代码一般都会走到注释2的分支去。 

注释2:传入intent,执行 startAcivity()。这个方法在Activity.java类中实现,由于Launcher是继承于Activity,所以在startActivitySafely中调用的startActivity方法其实就是Activity中的方法。 

我们来看看其代码:

// Activity.java
    @Override
    public void startActivity(Intent intent, @Nullable Bundle options) {
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            startActivityForResult(intent, -1);
        }
    }

都是走到 startActivityForResult() 中去,其中第一个参数为在Launcher中创建的Intent,第二个参数-1表示Launcher不需要知道Activity启动的结果。

也就是说Lancher只管发请求,之后怎么样就再也不处理了。

我们来看看 startActivityForResult() 的代码:

// Acitvity.java
 public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        // 1
        if (mParent == null) { 
            options = transferSpringboardActivityOptions(options);
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
             ...
        } else {
           ...
        }
    }

注释1:如果 mParent==null 则往下走 execStartActivity()
mParent是当前Activity的父类,因为根Activity还没有创建出来,所以mParent就是null。
接着调用 Instrumentation 类的 execStartActivity()

传入参数:this(上下文)、当前应用主线程、token、this(上下文)、Launcher来的intent、requstCode(-1,表示无需知道后面的结果)、携带参数bundle。

这里有两个参数很重要,我们发现有个 mMainThread 变量,这是一个 ActivityThread 类型的变量。

  • mMainThread.getApplicationThread(),通过ActivityThread的getApplicationThread方法取到一个Binder对象,它的类型为ApplicationThread,它代表着Launcher所在的App进程。
  • mToken,这也是个Binder对象,它代表了Launcher这个Activity,这里也通过Instrumentation传给AMS,AMS一查电话簿,就知道是谁向AMS发起请求了。

这两个参数是伏笔,传递给AMS,以后AMS想反过来通知Launcher,就能通过这两个参数,找到Launcher。 

这段内容的意思也就是将数据交给Instrumentation并由Instrumentation代为发起请求

解释:

    Instrumentation 负责调用Activity和Application生命周期。顾名思义,仪器、仪表,用于在应用程序中进行“测量”和“管理”工作。一个应用程序中只有一个Instrumentation实例对象,且每个Activity都有此对象的引用。Instrumentation将在任何应用程序运行前初始化。

接着我们来看看 Instrumentation 这个类的启动Activity的方法:

public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, String target,
        Intent intent, int requestCode, Bundle options) {
        ...
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()), // 1
                        token, target, requestCode, 0, null, options);  
            checkStartActivityResult(result, intent);         // 2
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

    在 try{ } 中,先修改一下intent的内容。
其次在注释1中:调用 ActivityManager.getService().startActivity() 一套组合拳。

    这条代码先从 ActivityManager.getService() 获取AMS在Client端的代理对象。也就是说,它会返回个可以看做是 AMS 的对象。然后调用其 startActivity(),也就是调用 AMS.startActivity()。即请求AMS(ActivityManagerService)的过程完成,开始执行下一阶段。     

解释:

    由于AMS是系统核心服务,很多API不能开放供客户端使用。所以在Android 7.0 需要在ActivityManager类内部通过getDefault函数得到一个AMP对象,通过它可与AMS通信。

而在Android 8.0 之后通过AIDL直接与AMS通信,与7.0的区别在于直接返回了一个AMS代理对象,没有了AMP。

    AIDL是Android接口定义语言

    在 Android 中,一个进程通常无法访问另一个进程的内存。因此,为进行通信,进程需将其对象分解成可供操作系统理解的原语,并将其编组为可供您操作的对象。编写执行该编组操作的代码较为繁琐,因此 Android 会使用 AIDL 为您处理此问题。(来自官方文档)

但进入下一阶段前,我们来看看 execStartActivity() 方法中如何获取AMS的代理对象,来看看 ActivityManager.getService() 中getServcie的代码:

// AcitvityManager.java
public static IActivityManager getService() {
      return IActivityManagerSingleton.get();
}

    这个方法返回一个IActivityManager的对象,有了解AIDL或代理模式的应该就能立马知道 IActivityManager 是AMS在客户端的代理类

我们来看看IActivityManagerSingleton的get:

// ActivityManager.java
  private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {
                    //1
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    //2
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };

注释1:从 ServiceManager 得到AMS的IBinder接口,也就是 “IBinder类型的AMS”

注释2:将IBinder通过 asInterface() 转换成一个 IActivityManager 对象,通过 get() 可以得到这个对象。这样就可以通知AMS启动activity。 

解释:

    IBinder是安卓开发中的一个接口。这个接口是能进行远程操作对象的一个基本接口。定义了为在提供进程间和跨进程间的调用时提供高性能的轻量级远程调用的核心部分。该接口描述了与远程对象进行交互的抽象协议。

 总结:第一步即Launcher收到用户点击图标的信息后,他开始准备各种参数,将参数发送给Instrumentation,由Instrumentation与AMS的代理对象进行沟通,请求AMS创建Activity。

 第二步:AMS到ApplicationThread的调用过程

Android优先启动activity android activity启动流程详解_Android优先启动activity_03

    可以看到,从AMS到ApplicaitonThread的过程就有些复杂了,图中会经过 ActivityStarter、ActivityStackSupervisor、ActivityStack这样的类。

我们先来看看最初始的 AMS(ActivityMangerService)的 startAcitivty() 方法: 

// ActivityManagerService.java
    @Override
    public final int startActivity(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions,
                UserHandle.getCallingUserId());
    }

    可以看到它return调用自己的 StartActivityAsUser() 可以看到在参数的对比上,后者多了一个 getCallingUserId(),顾名思义,这个方法可以获取到调用者的UserId,AMS就是根据这个UserId来确定调用者的权限的:

@Override
    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
        //1
        enforceNotIsolatedCaller("startActivity");
        //2
        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
        //3
        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
                profilerInfo, null, null, bOptions, false, userId, null, null,
                "startActivityAsUser");
    }

注释1:判断调用者进程是否被隔离(是否可用),如果被隔离则抛出异常。 

注释2:检查调用者是否有权限,是根据传进来的 userId进行判断的。如果没有权限也会抛出异常 

注释3:调用 ActivityStarter.startActivityMayWait()  这里需要注意的是倒数第二个参数 TaskRecord,代表启动Activity所在的栈,最后一个参数reason,代表启动Activity的理由。

解释:

ActivityStarter 是Android 7.0 中新加入的类,它是加载Activity的控制类
这个类的作用是根据传入的数据来把Intent转换成Activity的。 

我们来看看以下 startActivityMayWait()(启动预处理):

// ActivityStarter.java
 final int startActivityMayWait(IApplicationThread caller, int callingUid,
            String callingPackage, Intent intent, ... int userId,
            IActivityContainer iContainer, TaskRecord inTask, String reason) {
            ...
            int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
                    aInfo, rInfo, voiceSession, voiceInteractor..., container,
                    inTask, reason);
                    ...
            return res;
        }
    }

在这个方法里面,调用到了 startActivityLocked(),这个方法是通向后面启动Activity的方法,我们来看一下其源码:

// ActivityStarter.java
int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
            ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
            ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
            TaskRecord inTask, String reason) {

        if (TextUtils.isEmpty(reason)) {
            throw new IllegalArgumentException("Need to specify a reason.");
        }
        mLastStartReason = reason;
        mLastStartActivityTimeMs = System.currentTimeMillis();
        mLastStartActivityRecord[0] = null;

        mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
                aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
                callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
                container, inTask);
                ...
        return mLastStartActivityResult;
    }

这个方法就是处理了一下为什么要创建Activity的Reason这个String,对传过来的参数做一些校验,然后调用了 startActivity(),我们往下看:

private int startActivity(IApplicationThread caller...) {
        int err = ActivityManager.START_SUCCESS;
        final Bundle verificationBundle
                = options != null ? options.popAppVerificationBundle() : null;
        ProcessRecord callerApp = null;
        //1
         if (caller != null) {
            //2
            callerApp = mService.getRecordForAppLocked(caller);
            if (callerApp != null) {
                callingPid = callerApp.pid;
                callingUid = callerApp.info.uid;
            } else {
                Slog.w(TAG, "Unable to find app for caller " + caller
                        + " (pid=" + callingPid + ") when starting: "
                        + intent.toString());
                err = ActivityManager.START_PERMISSION_DENIED;
            }
        }
        ...
        //3 这里创建即将要启动的Activity的描述类ActivityRecord。
        ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
                callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
                resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
                mSupervisor, container, options, sourceRecord);
        if (outActivity != null) {
            outActivity[0] = r;
        }
        ...
        //4   
        return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
                options, inTask, outActivity);
}

注释1:判断 IApplicationThread 类型的caller是否为null,这个caller是方法调用一路传过来的,指向 Launcher所在应用程序进程的 ApplicationThread 对象。

注释2:调用AMS的 getRecordForAppLocked() 方法得到一个 代表Launcher进程的ProcessRecord 类的实例 callerApp。ProcessRecord 用来描述一个应用程序进程。

解释:

Android系统中用于描述进程的数据结构是ProcessRecord对象 

注释3:同样的,ActivityRecord 用来描述一个 Activity的所有信息。创建一个新的赋给r,然后r作为 outActivity第一个数据。
outActivity是 ActivityRecord[ ] 类型的数据。  

解释:

一个 ActivityRecord 对应一个 Activity,保存了一个Activity的所有信息;但是一个 Activity可能会有多个 ActivityRecord,因为 Activity 可以被多次启动,这个主要取决于其启动模式。

一个 TaskRecord 由一个或者多个 ActivityRecord 组成,这就是我们常说的任务栈,具有后进先出的特点。

ActivityStack 则是用来管理TaskRecord的,包含了多个TaskRecord。

注释4:把这个方法里面得出的所有参数,传到重载方法 startActivity() 中:

// ActivityStarter.java
   private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {
        int result = START_CANCELED;
        try {
            mService.mWindowManager.deferSurfaceLayout();
            //调用startActivityUnchecked
            result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, outActivity);
        } 
        ...
        return result;
    }

 这里返回 startActivityUnchecked() 这个函数:

// ActivityStarter
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {
        ...    
        //1
        if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
                && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
            newTask = true;
            //2 创建新的TaskRecord
            result = setTaskFromReuseOrCreateNewTask(
                    taskToAffiliate, preferredLaunchStackId, topStack);
        } else if (mSourceRecord != null) {
            result = setTaskFromSourceRecord();
        } else if (mInTask != null) {
            result = setTaskFromInTask();
        } else {
            setTaskToCurrentTopOrCreateNewTask();
        }
        ...
        if (mDoResume) {
            final ActivityRecord topTaskActivity =
                    mStartActivity.getTask().topRunningActivityLocked();
            if (!mTargetStack.isFocusable()
                    || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                    && mStartActivity != topTaskActivity)) {
                ...
            } else {
                if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
                    mTargetStack.moveToFront("startActivityUnchecked");
                }
                //3
                mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                        mOptions);
            }
        }
        ...

startActivityUnchecked() 它的作用主要是处理与栈管理相关的逻辑。所以这个方法就是我们新的Activity所处的栈的管理方法了。 

注释1:由于我们传入进来的Intent的FLAG是有 FLAG_ACTIVITY_NEW_TASK 这个属性的,所以能通过if

注释2:通过 setTaskFromReuseOrCreateNewTask,它会创建出一个 TaskRecord,前面说过,它用来描述一个任务栈,也是Activity最直观的表现类,之所以这么说,是因为任务栈是一个假象的模型,他实际并不存在,所以这个方法相当于创建了一个任务栈出来。

注释3:调用 ActivityStackSupervisor.resumeFocusedStackTopActivityLocked() ,这个方法从ActivityStarter深入到了 ActivityStackSupervisor,是往下走的一个方法。

解释:

ActivityStackSupervisor类 负责所有Activity栈的管理

我们来看看这个方法:

// ActivityStackSupervisor
boolean resumeFocusedStackTopActivityLocked(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
        if (targetStack != null && isFocusedStack(targetStack)) {
            return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }
        //1
        final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
        //2
        if (r == null || r.state != RESUMED) {
            //3
            mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
        } else if (r.state == RESUMED) {
            mFocusedStack.executeAppTransition(targetOptions);
        }
        return false;
    }

注释1:调用 ActivityStack.topRunningActivityLocked() 获取要启动的Activity所在栈的栈顶的不是处于停止状态的ActivityRecord

解释:

ActivityStack 则是用来管理TaskRecord的,包含了多个TaskRecord。

注释2:判断这个 ActivityRecord 是否为空或者要启动的Activity是不是 RESUMED(前台状态)状态,由于我们是创建根Activity,所以这个 r 是空的。所以它会调用注释3的代码

注释3:调用 ActivityStack.resumeTopActivityUncheckedLocked,这个方法名虽然长,但是我们可以知道它大概的意思就是 启动一个栈顶Activity。我们来看看这个方法: 

// ActivityStack
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
        ...
        boolean result = false;
        try {
            mStackSupervisor.inResumeTopActivity = true;
            //1
            result = resumeTopActivityInnerLocked(prev, options);
        } finally {
            mStackSupervisor.inResumeTopActivity = false;
        }
        mStackSupervisor.checkReadyForSleepLocked();
        return result;
    }

注释1:上面的代码在 try-catch里面,调用了 resumeTopActivityInnerLocked() 去置result。

我们来看看这个方法: 

// ActivityStack
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
     ...
         mStackSupervisor.startSpecificActivityLocked(next, true, true);
     }
     ..
}

因为这个方法代码非常多,所以我们来看它调用比较关键的代码就可以了,即调用了 ActivityStackSupervisor.startSpecificActivityLocked 回到了 ActivityStackSupervisor中

我们来看看这段代码:

// ActivitySupervisor
 void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
        // 1
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);
        r.getStack().setLaunchTime(r);
        if (app != null && app.thread != null) {
            try {
                ... 
                //2
                realStartActivityLocked(r, app, andResume, checkConfig);
                return;
            } 
            ...
        }

        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }

注释1:获取即将启动的Activity所在应用程序的进程。开篇说过需要知道应用程序进程是怎么启动的。因为一个应用程序要启动,最先要做的就是把这个应用程序的进程给启动。 ProcessRecord 就是描述一个应用进程的类。它由 AMS来管理。

注释2:由于进程已经启动了所以不为null,就会调用 realStartActivityLocked()。 

// ActivityStackSupervisor
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {
            ...
            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    System.identityHashCode(r), r.info,
                    mergedConfiguration.getGlobalConfiguration(),
                    mergedConfiguration.getOverrideConfiguration(), r.compat,
                    r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                    r.persistentState, results, newIntents, !andResume,
                    mService.isNextTransitionForward(), profilerInfo);
            ...
            return true; 
}

这个方法也非常的长,比较关键的就是这句.
app.thread 指的是 IApplicationThread,它的实现是ActivityThread的内部类 ApplicationThread,其中ApplicationThread继承了 IApplicationThread.Stub。也就是这里又使用了一次AIDL。
app是ProcessRecord,即应用程序所在的进程。
因此这段代码就是要在 目标应用程序进程启动Activity。
当前代码逻辑运行在 AMS所在的进程(即Server端/SystemServer进程)中,通过ApplicationThread来与应用程序进程进行Binder通信,换句话说,ApplicationThread是AMS和应用程序进程间的桥梁。他们的关系如下:

Android优先启动activity android activity启动流程详解_android_04

到这里,代码从AMS到了应用程序所在的进程中了。这也到了我们启动流程最后的一部分。 

总结:第二步即,AMS收到请求后,调用StartActivityAsUser()方法进行了一下请求者的权限确认,通过后,在ActivityStarter 这个类中根据传入的数据来把Intent转换成Activity,其中调用startActivityLocked() 处理了一下为什么要创建Activity的Reason这个String,得到ProcessRecord的实例用来描述一个应用程序进程,创建一个 ActivityRecord 用来描述一个 Activity的所有信息,在startActivityUnchecked() 中创建一个TaskRecord(相当于创建一个任务栈),然后进入ActivityStack 判断任务栈栈顶是否为空,因为是空,然后调用resumeTopActivityUncheckedLocked()方法创建一个Activity,然后再回到ActivityStackSupervisor中,调用startSpecificActivityLocked获取即将启动的Activity所在应用程序的进程,然后调用realStartActivityLocked()方法使AMS通过ApplicationThread来与应用程序进程进行Binder通信来高告诉目标应用程序进程启动Activity。

第三步:ActivityThread启动Activity的过程

Android优先启动activity android activity启动流程详解_应用程序_05

我们先从入口 ApplicationThread.scheduleLaunchActivity(),其中 ApplicaitonThread是ActivityThread的内部类。
在应用程序进程的创建中,进程创建后会运行这个进程的主线程Thread实例,即 ActivityThread,它管理当前应用程序的主线程。

// ActivityThread.java
        @Override
        public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
                CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
                int procState, Bundle state, PersistableBundle persistentState,
                List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
                boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {

            updateProcessState(procState, false);
            ActivityClientRecord r = new ActivityClientRecord();
            r.token = token;
            r.ident = ident;
            r.intent = intent;
            ...
            updatePendingConfiguration(curConfig);
            sendMessage(H.LAUNCH_ACTIVITY, r);
        }

这个方法把要启动的 Activity封装成一个 ActivityClientRecord,然后通过 sendMessage() 向H类发送类型为 H.LAUNCH_ACTIVITY 的消息,把这个封装好的对象给带上。来看看我们非常熟悉的sendMessage()吧:

// AcitivtyThread
final H mH = new H();

private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
        ...
        Message msg = Message.obtain();
        msg.what = what;
        msg.obj = obj;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        if (async) {
            msg.setAsynchronous(true);
        }
        mH.sendMessage(msg);
    }

这里的mh是 H 的实例,在应用程序进程的启动中,这个 H 是随着进程的启动而创建,它是 ActivityThread的内部类,并且继承自Handler,是应用程序进程中主线程的消息管理类,发送消息是通过 H 的 Handler 类来完成的。

解释:

这个H类相当于ActivityThread和ApplicationThread的中介人。
ActivityThread通过ApplicationThread与AMS通讯。
ApplicationThread通过H与ActivityThread通讯,处理Activity事务。

为什么明明都到了应用程序的进程中了,H、ApplicationThread都在ActivityThread类里,为何ApplicationThread还要通过Handler来发送消息呢?

是因为 ApplicationThread作为一个桥梁Binder,它的逻辑是运行在Binder线程池中的,因为接下来的流程要切到主线程中,所以就要通过Handler来实现一个线程的切换。

我们来看看 H 类的实现:  

//ActivityThread
        private class H extends Handler {
           //1
           public static final int LAUNCH_ACTIVITY         = 100;
           ...
           public void handleMessage(Message msg) {
            switch (msg.what) {
                case LAUNCH_ACTIVITY: {
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
                    //2
                    final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
                    //3
                    r.packageInfo = getPackageInfoNoCheck(
                            r.activityInfo.applicationInfo, r.compatInfo);
                    //4
                    handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;
            ...
          }

首先 H 继承了Handler,它实现了 sendMessage() 、handleMessage() 等方法

注释1:定义了 LAUNCH_ACTIVITY 消息字段,然后在 handleMessage() 中处理。代码走下来就一定会走到这个case中

注释2:从消息message中拿出里面 ActivityClientRecord,即封装好的 Activity信息。

注释3:通过 getPackageInfoNoCheck()来获得 LoadedApk 类型的对象,并赋值给 ActivityClientRecord的 packageInfo 属性。

解释:

应用程序进程要启动Activity时需要将Activity所属的APK加载进来,而 LoadedApk 就是用来描述已加载的 APK文件的。 

注释3:调用 handleLaunchActivity(),我们来看看其代码: 

// ActivityThread.java
 private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
        ...
        WindowManagerGlobal.initialize();
        //1 
        Activity a = performLaunchActivity(r, customIntent);

        if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            reportSizeConfigurations(r);
            Bundle oldState = r.state;
            //2
            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);

            if (!r.activity.mFinished && r.startsNotResumed) {
                performPauseActivityIfNeeded(r, reason);
                if (r.isPreHoneycomb()) {
                    r.state = oldState;
                }
            }
        } else {
            try {
                //停止Activity的启动
                ActivityManager.getService()
                    .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                            Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }
    }

注释1:performLaunchActivity() 可以说是主线程的第一个关键方法,它的作用是启动Activity,如果成功启动则会返回一个Activity实例。

注释2:handleResumeActivity() 用来将 Activity 的状态设置成 Resume。

如果该Activity为null,通知AMS终止行动。下面来看看 performLaunchActivity()

// ActivityThread
   private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ...
        //1 获取 Actiivty的 ActivityInfo类
        ActivityInfo aInfo = r.activityInfo;
        if (r.packageInfo == null) {
            //2 获取APK文件描述类 LoadedApk
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        }
        //3
        ComponentName component = r.intent.getComponent();
        ....
        //4
        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            //5
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            ...
        } catch (Exception e) {
            ...
        }
        try {
            //6
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
            ...
            if (activity != null) {
                //7
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window, r.configCallback);

                ...
                if (r.isPersistable()) {
                    //8
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } 
                ...
    }

这个方法做的事情有点多,它的目标是通给给定的一个 Activity描述类 -> Activity实例,我们来分析每个注释

注释1:获取ActivityInfo,它用于存储代码以及 AndroidManifest设置的该Acitivty和Receiver等节点信息,比如我们熟知的 launchMode(启动模式)

注释2:获取LoadedApk,前面也做过,这里如果没有就再做一次

注释3:获取要启动Activity的 ComponentName 类,这个类保存了 Activity的包名和类名

注释4:创建要启动Activity的上下文环境ContextImpl

注释5:根据ComponentName中存储的Activity类名,用 类加载器来创建该Activity的实例。

注释6:创建Application,makeApplication() 内部会调用Application的 onCreate()

注释7:调用Activity的 attach() ,这个方法用来初始化一个 Activity。在  attach() 中会创建 Window(PhoneWindow)对象并与 Activity自身进行关联。

解释:

Window 类是一个抽象类,提供了绘制窗口的一组通用API。可以将之理解为一个载体,各种View在这个载体上显示。

PhoneWindow 类继承于Window类,是Window类的具体实现,即我们可以通过该类具体去绘制窗口。并且,该类内部包含了一个DecorView对象,该DectorView对象是所有应用窗口(Activity界面)的根View。 简而言之,PhoneWindow类是把一个FrameLayout类即DecorView对象进行一定的包装,将它作为应用窗口的根View,并提供一组通用的窗口操作接口。它是Android中的最基本的窗口系统,每个Activity 均会创建一个PhoneWindow对象,是Activity和整个View系统交互的接口。

DecorView对象 是PhoneWindow类的内部类(后面版本将DecorView拿出来了)。该类是一个FrameLayout的子类,并且是PhoneWindow的子类,该类就是对普通的FrameLayout进行功能的扩展,更确切点可以说是修饰(Decor的英文全称是Decoration,即“修饰”的意思),比如说添加TitleBar(标题栏),以及TitleBar上的滚动条等 。最重要的一点是,它是所有应用窗口的根View 。

注释8:调用 Instrumentation.callActivityOnCreate()

我们来看看这个方法:

// Instrumentation.java
public void callActivityOnCreate(Activity activity, Bundle icicle,
            PersistableBundle persistentState) {
        prePerformCreate(activity);
        //1
        activity.performCreate(icicle, persistentState);
        postPerformCreate(activity);
    }

注释1调用了 performCreate() ,我们来看下这个方法:

// Activity.java
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
        restoreHasCurrentPermissionRequest(icicle);
        onCreate(icicle, persistentState);
        mActivityTransitionState.readState(icicle);
        performCreateCommon();
    }

这段代码中,调用了 Activity.onCreate()。这个方法就是我们写的Acitivty的 super.onCreate 方法了。
至此,Activity启动的流程就结束了。这个方法走完后,就会通过一开始ActivityThread的 handleResumeActivity() 走Activity的 onResume了。

总结: 从第二步AMS调用 scheduleLaunchActivity() 方法,这个方法把要启动的 Activity封装成一个 ActivityClientRecord 类的对象,传递到ApplicationThread,虽然 ApplicaitonThread 是 ActivityThread 的内部类,但因为ApplicationThread通过H与ActivityThread通讯,所以通过 sendMessage() 向H类发送类型为 H.LAUNCH_ACTIVITY 的消息,把这个封装好的对象(ActivityClientRecord)给带上。到了H类中调用 handleMessage() 方法,从消息message中拿出里面 ActivityClientRecord 即封装好的 Activity信息,通过 getPackageInfoNoCheck() 来获得 LoadedApk 类型的对象(而 LoadedApk 就是用来描述已加载的 APK文件的),然后调用 handleLaunchActivity() 方法并把刚获得的参数传入,然后在 handleLaunchActivity() 中调用 performLaunchActivity() 方法,在这个方法中会 将Activity描述类 -> Activity实例 其中调用了Instrumentation.callActivityOnCreate() 方法,这个方法中又调用了 performCreate() 方法,这个方法中就包含着我们熟悉的 Activity.onCreate() 方法,这样Activity的启动就结束了。