根 Activity 启动过程笔源码分析笔记

源码基于 Android 7.1.2

知识基础:Binder 机制
且下文中提到的 Binder 代理类是指持有 binder 引用对象的 Proxy 类,例如 ActivityManagerProxy,该类里面的 binder 引用对象指向远程进程里的 binder 本地对象。

主要参考文章:
Android 7.1.2(Android N) Activity启动流程分析,以及 《Aandroid 进阶解密》。


先放一个整体的建议流程图(图片来源互联网,如涉及版权问题,请私聊本人,将及时处理)
在这里插入图片描述

概述:

涉及到的对象

  1. ActivityRecord:用于记录 Activity 信息,每个启动的 Activity 在 ActivityManagerService(后面简称 AMS)进程中,都会有唯一对应的 ActivityRecord 对象实例。

  2. ActivityClientRecord:每个启动的 Activity 在自身进程中都有唯一一个对应的 ActivityClientRecord 对象,主要是对 Activity 的状态进行记录。该实例一一对应于 AMS 中的 ActivityRecord 实例。

  3. ActivityThread:App 的真正入口。当开启 App 之后,会调用其 main() 方法(静态方法)开始运行,开启消息循环队列,而调用其 main() 方法的线程即 UI 线程(主线程)。(ActivityThread 并不是传统意义上的 Thread 类,因为其没有继承自 Thread,而是运行在主线程的对象,其保存了关于进程、主线程相关的内容,详细后面会说)

  4. ApplicationThread :ActivityThread 的静态内部类,继承自 ApplicationThreadNative,本质上为 Binder 对象。每个 App 都包含该 binder 本地对象,用于实现 AMS 与当前 ActivityThread 进行交互。在 AMS 需要管理相关 Application 中的 Activity 的生命周期时,通过ApplicationThread 的 **binder 代理对象 ** 与 ActivityThread 通讯。

  5. ApplicationThreadProxy:ApplicationThread 的 binder 代理对象对应的代理类(因为 ApplicationThreadProxy 自身并不是 IBinder 类型,只不过其持有 IBinder 类型的成员变量,即 binder 代理对象),在服务端(即 AMS 进程中)使用,通过该类的实例,可以实现与客户端(即目标应用进程端)的 binder 本地对象进行通讯。

  6. ProcessRecord:用于描述进程的数据结构,每一个应用进程都在 AMS 中对应一个 ProcessRecord 实例,而该实例又保存了 IApplicationThread 类型(实际上即 ApplicationThreadProxy 类型)对应的成员变量 thread,从而使 AMS 可以与客户端进行通讯。


一、Launcher 请求 AMS 的过程

点击桌面的应用图标,会通 Launcher 请求 AMS 启动对应的应用程序(Launcher 实际上也是 Activity),此时有:

Launcher # startActivitySafely()
// 在 startActivitySafely() 中会为 intent 添加 Intent.FLAG_ACTIVITY_NEW_TASK 的 flag 
->
Activity # startActivity(intent,optsBundle)
-> // 最终会调用如下方法
Activity # startActivityForResult(intent,-1,options) {
    if (mParent == null) {
        options = transferSpringboardActivityOptions(options);
        Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                    // mMainThread.getApplicationThread() 就是 Launcher Activity 所属进程的 ApplicationThread 本地 (Binder) 对象
                    // mToken(IBinder 类型) 是 Launcher Activity 在 MAS 中对应 ActivityRecord 的 Binder 代理对象
                this, mMainThread.getApplicationThread(), mToken, this,
                intent, requestCode, options);
        // 对于正常的启动根 Activity,mInstrumentation.execStartActivity() 返回的值为 null
        // 因此不会进入该 if 逻辑
        if (ar != null) {
        	...
        }
        ...
    }
    ...
}

进而,会通过 Instrumentation#execStartActivity() 方法来启动根 Activity。此时,对几个传递的参数做出说明:

mMainThread.getApplicationThread(),当前 Launcher Activity 所属进程的 ApplicationThread 本地 (Binder) 对象。
mToken,IBinder 类型,是 Launcher Activity 在 MAS 中对应 ActivityRecord 的 binder 代理对象。通过它,就可以找到 AMS 中对应于 Launcher Activity 的 ActivityRecord 实例。

// Instrumentation.java
public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
    IApplicationThread whoThread = (IApplicationThread) contextThread;
    ...
    try {
        intent.migrateExtraStreamToClipData();
        intent.prepareToLeaveProcess(who);
        int result = ActivityManagerNative.getDefault()
            .startActivity(whoThread, who.getBasePackageName(), intent,
                    intent.resolveTypeIfNeeded(who.getContentResolver()),
                    token, target != null ? target.mEmbeddedID : null,
                    requestCode, 0, null, options);
        checkStartActivityResult(result, intent);
    } catch (RemoteException e) {
        throw new RuntimeException("Failure from system", e);
    }
    return null;
}
// ActivityManagerNative.java
static public IActivityManager getDefault() {
	// gDefault.get() 会返回 Singleton#onCreate() 方法的返回值
    return gDefault.get();
}

private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
    protected IActivityManager create() {
    	// IBinder 类型的 b 即 AMS 的 binder 引用对象,指向远程进程里的 binder 本地对象,
    	// 即指向 AMS(AMS 继承自 Binder)
        IBinder b = ServiceManager.getService("activity"); 
        IActivityManager am = asInterface(b);
        return am;
    }
};

static public IActivityManager asInterface(IBinder obj) {
    if (obj == null) {
        return null;
    }
    IActivityManager in =
        (IActivityManager)obj.queryLocalInterface(descriptor);
    if (in != null) {
        return in;
    }
    return new ActivityManagerProxy(obj);
}

通过 ActivityManagerNative.getDefault() 可以获得 AMS 对应的 binder 代理对象,即 ActivityManagerProxy 实例,从而实现远程调用 AMS 进程的 startActivity() 方法。即 Launcher 请求 AMS 过程是基于 Binder 机制的。

因此,实际上是调用 ActivityManagerProxy#startActivity()

/**
 * caller: 从 Activity#startActivityForResult() 中传递过来的 ApplicationThread
 * callingPackage: 为 Launcher Activity 类型 Context#getBasePackageName() 获取当前Launcher Activity 所在包名
 * intent: 为关于要启动的根 Activity 时的意图
 * resolvedType: 通过 intent.resolveTypeIfNeeded() 方法得到的 itente 的 MIME data type
 * resultTo: 从 Activity#startActivityForResult() 中传递过来的 Launcher#mToken
 * resultWho: Launcher#mEmbeddedID
 * requestCode == -1
 * startFlag == 0
 * profilerInfo == null
 * options: 从 Launcher#startActivitySafely() 中传递过来的,可能为 null
 */
public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
        String resolvedType, IBinder resultTo, String resultWho, int requestCode,
        int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
    Parcel data = Parcel.obtain();
    Parcel reply = Parcel.obtain();
    // 将需要数据写入 Parcel 中进行远程通信
    data.writeInterfaceToken(IActivityManager.descriptor);
    ...
    // 基于 Binder 机制切换到 AMS 进程
    mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
    reply.readException();
    int result = reply.readInt();
    reply.recycle();
    data.recycle();
    return result;
}

其中,会利用 mRemote,基于 Binder 机制实现与 AMS 远程通信,mRemote 实际为 ActivityManagerNative(AMS 继承自它)类型的 binder 引用对象,调用 AMS#startActivity() 方法(看下面的源码)。

// ActivityManagerNative.java
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
        throws RemoteException {
    switch (code) {
    case START_ACTIVITY_TRANSACTION:
    {
        data.enforceInterface(IActivityManager.descriptor);
        IBinder b = data.readStrongBinder();
        IApplicationThread app = ApplicationThreadNative.asInterface(b);
        String callingPackage = data.readString();
        Intent intent = Intent.CREATOR.createFromParcel(data);
        String resolvedType = data.readString();
        IBinder resultTo = data.readStrongBinder();
        String resultWho = data.readString();
        int requestCode = data.readInt();
        int startFlags = data.readInt();
        ProfilerInfo profilerInfo = data.readInt() != 0
                ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
        Bundle options = data.readInt() != 0
                ? Bundle.CREATOR.createFromParcel(data) : null;
        // 调用 AMS#startActivity()
        int result = startActivity(app, callingPackage, intent, resolvedType,
                resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
        reply.writeNoException();
        reply.writeInt(result);
        return true;
    }
    ...
}

基于 Binder 机制,切换到 AMS 进程后,会调用 AMS#startActivity()

二、AMS 进程中的调用过程
// 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,
            // 因为现在的 Android 支持多用户模式,因此这里获得调用者对应的 UserId
            UserHandle.getCallingUserId());
}

@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) {
    // 判断调用者进程是否被隔离,即如果进程是沙箱进程则直接抛出安全异常
    enforceNotIsolatedCaller("startActivity");
    // UserController 是多用户功能的用户管理者,一些系统包含访客模式,或者多用户,每个用户就会有一个 id
    // 这里会检查调用者权限
    userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
            userId, false, ALLOW_FULL_ONLY, "startActivity", null);
    // TODO: Switch to user app stacks here.
    // 在这里会切换到 app 对应的栈
    return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
            resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
            profilerInfo, null, null, bOptions, false, userId, null, null);
}

之后,会调用 ActivityStarter#startActivityMayWait()

// ActivityStarter.java

/**
 * 
 * caller: ApplicationThreadProxy,用于跟调用者进程的 ApplicationThread 通信的 binder 代理类,
 * 		  从调用者进程传递过来 binder 引用之后,在 ActivityManagerNative#onTransact() 中被包装成
 * 		  ApplicationThreadProxy 的,当前情景即对应 Launcher Activity 进程的 ApplicationThread 
 * 		  的 binder 代理类
 * callingUid: -1
 * callingPackage: 调用者 Activity 对应的包名,当前情景即 Launcher Activity 对应的包名,
 * 				   从调用着进程传递过来的
 * intent: 启动 Activity 时传递过来的参数
 * resolvedType: 从调用者进程传递过来的通过 intent.resolveTypeIfNeeded() 方法得到的 itente 的 MIME data type
 * voiceSession: null
 * voiceInteractor: null
 * resultTo: 从调用者进程的 Activity 传递过来的,即 Launcher Activity#startActivityForResult() 
 * 			 中传递过来的 Launcher#mToken
 * resultWho: 从调用者进程传递过来的,即 Launcher Activity#mEmbeddedID
 * requestCode: 从调用者进程传递过来的,为 -1
 * startFlags: 从调用者进程传递过来的,为 0
 * profilerInfo: 从调用者进程传递过来的,但是对于根 Activity 启动的情景,此时为 null
 * outResult: null
 * config: null
 * bOptions: 从调用者进程传递过来的(即从 Launcher#startActivitySafely() 中传递过来的),可能为 null
 * ignoreTargetSecurity: false
 * userId: 从 AMS#startActivity() 中传过来的 UserHandle.getCallingUserId()
 * iContainer: null
 * inTask: null
 * 
 */
final int startActivityMayWait(IApplicationThread caller, int callingUid,
        String callingPackage, Intent intent, String resolvedType,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        IBinder resultTo, String resultWho, int requestCode, int startFlags,
        ProfilerInfo profilerInfo, IActivityManager.WaitResult outResult, Configuration config,
        Bundle bOptions, boolean ignoreTargetSecurity, int userId,
        IActivityContainer iContainer, TaskRecord inTask) {
    ...
    // Save a copy in case ephemeral needs it
    final Intent ephemeralIntent = new Intent(intent);
    // Don't modify the client's object!
    intent = new Intent(intent);
    // 在 mSupervisor.resolveIntent() 中会通过 PackageManager 解析需要启动的 intent 信息,
    // 得到 ResolveInfo
    ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
    ...
    // Collect information about the target of the Intent.
    // 得到 itent 对应的 ActivityInfo
    ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
    ActivityOptions options = ActivityOptions.fromBundle(bOptions);
    ActivityStackSupervisor.ActivityContainer container =
            (ActivityStackSupervisor.ActivityContainer)iContainer;
    synchronized (mService) {
        ...
        // 类似于 C 语言里面传递指针,这里会将 outRecord 数组传递给 startActivityLocked() 方法,
        // 在该方法的执行过程中会将 outRecord[0] 给赋值,
        // 然后就可以在本方法中的执行完 <int res = startActivityLocked()> 的这段逻辑之后引用 outRecord[0] 对应的内容,
        // 而不是以方法返回值的形式,因为返回值另有内容与作用
        final ActivityRecord[] outRecord = new ActivityRecord[1];
        // 调用 startActivityLocked() 方法
        int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
                aInfo, rInfo, voiceSession, voiceInteractor,
                resultTo, resultWho, requestCode, callingPid,
                callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                options, ignoreTargetSecurity, componentSpecified, outRecord, container,
                inTask);
        ...
        // 这里就有引用到 outRecord[0]
        final ActivityRecord launchedActivity = mReusedActivity != null
                ? mReusedActivity : outRecord[0];
        mSupervisor.mActivityMetricsLogger.notifyActivityLaunched(res, launchedActivity);
        return res;
    }
}

// 然后进一步调用 startActivityLocked()
final 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) {
    int err = ActivityManager.START_SUCCESS;
    // 根据从调用着进程(即 Launcher Activity 所处进程)中传递过来的 ApplicationThreadProxy,
    // 即 binder 代理类,来得到在 AMS 中 Launcher Activity 对应的 ProcessRecord 对象 callerApp
    ProcessRecord callerApp = null;
    if (caller != null) {
        callerApp = mService.getRecordForAppLocked(caller);
        if (callerApp != null) {
            // 得到进程 id -> callingPid
            callingPid = callerApp.pid;
            // 得到用户id -> callingUid
            callingUid = callerApp.info.uid;
        } else {
            err = ActivityManager.START_PERMISSION_DENIED;
        }
    }
    final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
    ...
    ActivityRecord sourceRecord = null;
    ActivityRecord resultRecord = null;
    if (resultTo != null) {
        // resultTo,就是从 Activity#startActivityForResult() 中传递过来的 Activity#myToken,
        // Activity#myToken 为 IBinder 类型,用于标识在 AMS 中对应的 ActivityRecord 对象
        // (对于根 Activity 的启动来说,即从 Launcher(Activity)中传递过来的,
        // 因此 sourceRecord 即为 Launcher 在 AMS 中对应的 ActivityRecord)
        sourceRecord = mSupervisor.isInAnyStackLocked(resultTo);
        if (sourceRecord != null) {
         	// 此时 requestCode == -1
            if (requestCode >= 0 && !sourceRecord.finishing) {
                resultRecord = sourceRecord;
            }
        }
    }
    ... 
    
    // 用前面得到的 callApp、callingUid,以及从上层方法得到且传递过来的 aInfo,
    // 构造需要启动的 Activity(以启动根 Activity 的情景来说) 对应的 ActivityRecord r
    ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
            intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
            requestCode, componentSpecified, voiceSession != null, mSupervisor, container,
            options, sourceRecord);
    if (outActivity != null) {
        outActivity[0] = r;
    }
    ...
    try {
        mService.mWindowManager.deferSurfaceLayout();
        // 进一步调用 startActivityUnchecked()
        // r 为需要启动的 MainActivity 对应的 ActivityRecord
        err = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
                true, options, inTask);
    } 
    ...
    return err;
}
// startActivityLocked() 主要是构造出要启动的根 Activity 对应的 ActivityRecord,
// 之后进一步调用 startActivityUnchecked()

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {
    ... 
    boolean newTask = false;
    final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
            ? mSourceRecord.task : null;
    // Should this be considered a new task?
    // 启动根 Activity 的时候,会将 Intent 的 Flag 设置为 FLAG_ACTIVITY_NEW_TASK
    if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
            && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
        newTask = true;
        // 内部会创建一个新的 TaskRecord,并赋值给 mStartActivity
        //(即需要启动根 Activity 对应的 ActivityRecord 实例) 的 task 成员变量
        setTaskFromReuseOrCreateNewTask(taskToAffiliate);
        ...
    }
    ...
    // (1) 调用 TargetStack#startActivityLocked()
    // 会将根 Activity 对应的 ActivityRecord 放在任务栈的栈顶(对于根 Activity 的启动这一场景来说),
    // 并处理和 WindowManagerService 之间的交互。
    mTargetStack.startActivityLocked(mStartActivity, newTask, mKeepCurTransition, mOptions);
    // 是否将 Activity 处理成 resume 状态(即显示状态),此时 mDoResume == true
    // 当然这里并不是直接对 Activity 进行操作,因为此时并不涉及到 Activity 实例,而是与 ActivityRecord 有关,
    // 只有进入到该判断语句中,才会正常的进行根 Activity 启动的后续逻辑
    if (mDoResume) {
        if (!mLaunchTaskBehind) {
            // TODO(b/26381750): Remove this code after verification that all the decision
            // points above moved targetStack to the front which will also set the focus
            // activity.
            mService.setFocusedActivityLocked(mStartActivity, "startedActivity");
        }
        final ActivityRecord topTaskActivity = mStartActivity.task.topRunningActivityLocked();
        if (!mTargetStack.isFocusable()
                || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                && mStartActivity != topTaskActivity)) {
            // If the activity is not focusable, we can't resume it, but still would like to
            // make sure it becomes visible as it starts (this will also trigger entry
            // animation). An example of this are PIP activities.
            // Also, we don't want to resume activities in a task that currently has an overlay
            // as the starting activity just needs to be in the visible paused state until the
            // over is removed.
            mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
            // Go ahead and tell window manager to execute app transition for this activity
            // since the app transition will not be triggered through the resume channel.
            mWindowManager.executeAppTransition();
        } else {
            // (2) 调用 ActivityStackSupervisor 的 resumeFocusedStackTopActivityLocked() 方法
            mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                    mOptions);
        }
    } else {
        mTargetStack.addRecentActivityLocked(mStartActivity);
    }
    ...
    return START_SUCCESS;
}

ActivityStarter#startActivityMayWait() 中,会得到根 Activity 对应的 ActivityInfo;

ActivityStarter#startActivityLocked() 中,会进一步得到对应的 ActivityRecord;

ActivityStarter#startActivityUnchecked() 方法中主要为了处理与任务栈管理相关的逻辑,在该方法中会针对要启动的根 Activity 创建一个新的 TaskRecord,且该方法中又涉及到两个方法的调用:

(1) TargetStack#startActivityLocked():就有涉及到处理与任务栈管理相关的逻辑,在该方法中,会将根 Activity 对应的 ActivityRecord 放在任务栈(TaskRecord)的栈顶(对于根 Activity 的启动这一场景来说),并处理和 WindowManagerService 之间的交互。

具体可以参阅:http://duanqz.github.io/2016-07-29-Activity-LaunchProcess-Part1#5-asstartactivitylocked

(2) ActivityStackSupervisor#resumeFocusedStackTopActivityLocked(),该方法则是涉及根 Activity 启动的后续逻辑。

// ActivityStackSupervisor.java
boolean resumeFocusedStackTopActivityLocked(
        ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
    // 如果目标栈存在并且处于聚焦状态,直接启动
    if (targetStack != null && isFocusedStack(targetStack)) {
        return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
    }
    // 如果目标栈不存在或者没有在聚焦状态,则从聚焦栈中取出不是处于停止状态(即非 finishing 状态)的 ActivityRecord
    final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
    if (r == null || r.state != RESUMED) {
        mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
    }
    return false;
}

ActivityStackSupervisor 负责管理 Task 和 Stack, 而 ActivityStack 负责管理在 Stack 和 Task 中的 Activity。

来到 ActivityStackSupervisor#resumeFocusedStackTopActivityLocked() 之后,暂时还不确定是走

targetStack.resumeTopActivityUncheckedLocked(target, targetOptions)

还是

// 但是《Android 进阶解密》中说的会走这一个逻辑,先假定是正确的
mFocusedStack.resumeTopActivityUncheckedLocked(null, null)

之后会进入到 ActivityStack#resumeTopActivityUncheckedLocked() 中。(按照 《Android 进阶解密》中走的那一个逻辑,此时传递过来的 prev 和 options 均为 null。)

// AvtivityStack.java
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
	// inResumeTopActivity 用于保证每次只有一个 Activity 执行 resumeTopActivityUncheckedLocked() 操作
    if (mStackSupervisor.inResumeTopActivity) {
        // Don't even start recursing.
        return false;
    }
    boolean result = false;
    try {
        // Protect against recursion.
        mStackSupervisor.inResumeTopActivity = true;
        if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
            mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
            mService.updateSleepIfNeededLocked();
        }
        // 又会进一步调用 resumeTopActivityInnerLocked()
        result = resumeTopActivityInnerLocked(prev, options);
    } finally {
        mStackSupervisor.inResumeTopActivity = false;
    }
    return result;
}

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    // 先暂停其他 Activity(使其执行 onPause()),这里即 Launcher Activity
    // We need to start pausing the current activity so the top one can be resumed...
    final boolean dontWaitForPause = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0;
    boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, dontWaitForPause);
    if (mResumedActivity != null) {
    	...
    	// 调用 startPausingLocked(),中断正在显示的 Activity
        pausing |= startPausingLocked(userLeaving, false, next, dontWaitForPause);
    }
    ...
    
    if (next.app != null && next.app.thread != null) {
        ...
    } else {
        ...
        // 进一步调用 mStackSupervisor.startSpecificActivityLocked()
        mStackSupervisor.startSpecificActivityLocked(next, true, true);
    }
    ...
    return true;
}

AvtivityStack#resumeTopActivityInnerLocked() 中,会把当前的 Activity 暂停,即执行其 onPause()

接着,会调用 ActivityStackSupervisor#startSpecificActivityLocked()

// ActivityStackSupervisor.java
void startSpecificActivityLocked(ActivityRecord r,
        boolean andResume, boolean checkConfig) {
    // Is this activity's application already running?
    // 获取即将启动的根 Activity 对应的 ProcessRecord
    ProcessRecord app = mService.getProcessRecordLocked(r.processName,
            r.info.applicationInfo.uid, true);
    r.task.stack.setLaunchTime(r);
    // 如果需要启动的 Activity 所需要的应用进程是否已经启动(即是否已经存在),
    // 如果已经启动,则直接调用 realStartAtivityLocked()方法,
    // 否则调用 AMS#startProcessLocked() 方法,用于创建并启动应用进程
    if (app != null && app.thread != null) {
        try {
            if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                    || !"android".equals(r.info.packageName)) {
                // Don't add this if it is a platform component that is marked
                // to run in multiple processes, because this is actually
                // part of the framework so doesn't make sense to track as a
                // separate apk in the process.
                app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                        mService.mProcessStats);
            }
            realStartActivityLocked(r, app, andResume, checkConfig);
            return;
        } catch (RemoteException e) {
            ...
        }
    }
    // 如果应用进程不存在,则会先创建并启动该进程
    mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
            "activity", r.intent.getComponent(), false, false, true);
}

ActivityStackSupervisor#startSpecificActivityLocked() 中,会判断要启动的 Activity 对应的进程是否存在,存在的则直接调用 realStartActivityLocked()方法(对于这种情况,realStartActivityLocked() 方法会在后面有有讲解到);否则,会先创建该进程。


三、创建根 Activity 对应的应用进程

对于根 Activity 来说,如果是调用首次启动的根 Activity,此时对应的进程肯定是不存在的,所以需要先创建该进程。

对于在 ActivityStackSupervisor#startSpecificActivityLocked() 中调用的 AMS#startProcessLocked()

// AndroidManagerService.java

/**
 * 传递过来的参数的值
 * 
 * processName
 * info
 * knownToBeDead: true
 * intentFlags: 0
 * hostingType: "activity"
 * hostingName
 * allowWhileBooting: false
 * isolated: false
 * keepIfLarge: true
 * 
 */
final ProcessRecord startProcessLocked(String processName,
        ApplicationInfo info, boolean knownToBeDead, int intentFlags,
        String hostingType, ComponentName hostingName, boolean allowWhileBooting,
        boolean isolated, boolean keepIfLarge) {
        
    return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
            hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
            null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
            null /* crashHandler */);
}
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
        boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
        boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
        String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
    long startTime = SystemClock.elapsedRealtime();
    ProcessRecord app;
    ...
    String hostingNameStr = hostingName != null
            ? hostingName.flattenToShortString() : null;
    if (app == null) {
        checkTime(startTime, "startProcess: creating new process record");
        // 生成一个新的 ProcessRecord
        app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
        ...
    } else {
        ...
    }
    ...
    // 实例化 ProcessRecord 之后,调用 startProcessLocked()
    startProcessLocked(
            app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
    checkTime(startTime, "startProcess: done starting proc!");
    return (app.pid != 0) ? app : null;
}

private final void startProcessLocked(ProcessRecord app, String hostingType,
        String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) 
	...
    try {
        
        // Start the process.  It will either succeed and return a result containing
        // the PID of the new process, or else throw a RuntimeException.
        boolean isActivityProcess = (entryPoint == null);
        if (entryPoint == null) entryPoint = "android.app.ActivityThread";
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
                app.processName);
        checkTime(startTime, "startProcess: asking zygote to start proc");
        // 启动进程,并传入要启动的类名 entryPoint == "android.app.ActivityThread"
        Process.ProcessStartResult startResult = Process.start(entryPoint,
                app.processName, uid, uid, gids, debugFlags, mountExternal,
                app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
                app.info.dataDir, entryPointArgs);
        checkTime(startTime, "startProcess: returned from zygote!");
        ...
        // 在创建了新进程之后,会把其对应的 pid 保存到 app(ProcessRecord) 中
        app.setPid(startResult.pid);
        ...
        // 并且把 app 根据对应的 pid 保存到 mPidsSelfLocked(SparseArray<ProcessRecord> 类型) 中
        synchronized (mPidsSelfLocked) {
    		this.mPidsSelfLocked.put(startResult.pid, app);
    		...
		}
    } catch (RuntimeException e) {
        ...
    }
}

startProcessLocked() 中,会创建新建进程对应的 ProcessRecord 实例,且最终会调用 Process.start() 去启动目标进程,在创建目标进程之后,会将该进程对应的 pid 赋值给 ProcessRecord#pid,并把该 ProcessRecord 实例给保存下来。

// Process.java
// processClass == "android.app.ActivityThread"
public static final ProcessStartResult start(final String processClass,
                              final String niceName,
                              int uid, int gid, int[] gids,
                              int debugFlags, int mountExternal,
                              int targetSdkVersion,
                              String seInfo,
                              String abi,
                              String instructionSet,
                              String appDataDir,
                              String[] zygoteArgs) {
    try {
        return startViaZygote(processClass, niceName, uid, gid, gids,
                debugFlags, mountExternal, targetSdkVersion, seInfo,
                abi, instructionSet, appDataDir, zygoteArgs);
    } catch (ZygoteStartFailedEx ex) {
        Log.e(LOG_TAG,
                "Starting VM process through Zygote failed");
        throw new RuntimeException(
                "Starting VM process through Zygote failed", ex);
    }
}

private static ProcessStartResult startViaZygote(final String processClass,
                              final String niceName,
                              final int uid, final int gid,
                              final int[] gids,
                              int debugFlags, int mountExternal,
                              int targetSdkVersion,
                              String seInfo,
                              String abi,
                              String instructionSet,
                              String appDataDir,
                              String[] extraArgs)
                              throws ZygoteStartFailedEx {
    synchronized(Process.class) {
        ...
        return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
    }
}

可以看到,startViaZygote() 方法最终会返回:

zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote)

其中,openZygoteSocketIfNeeded() 方法会去尝试打开关于 Zygote 进程的 Socket 连接(如果还没有打开话;如果已经打开了,则不做操作)。

这里,就验证了最开始的那张图,创建根 Activity 对应的进程时是通过 Socket 来与 Zygote 进程通信的。

zygoteSendArgsAndGetResult() 方法则会利用(关于 Zygote 进程的)Socket 连接与 Zygote 进程通信,从而创建目标子进程,并返回该子进程的 pid。(zygoteSendArgsAndGetResult() 方法是阻塞的,当从 Zygote 进程得到结果之前。)

private static ProcessStartResult zygoteSendArgsAndGetResult(
        ZygoteState zygoteState, ArrayList<String> args)
        throws ZygoteStartFailedEx {
    try {
        // Throw early if any of the arguments are malformed. This means we can
        // avoid writing a partial response to the zygote.
        int sz = args.size();
        for (int i = 0; i < sz; i++) {
            if (args.get(i).indexOf('\n') >= 0) {
                throw new ZygoteStartFailedEx("embedded newlines not allowed");
            }
        }
        /**
         * See com.android.internal.os.ZygoteInit.readArgumentList()
         * Presently the wire format to the zygote process is:
         * a) a count of arguments (argc, in essence)
         * b) a number of newline-separated argument strings equal to count
         *
         * After the zygote process reads these it will write the pid of
         * the child or -1 on failure, followed by boolean to
         * indicate whether a wrapper process was used.
         */
        final BufferedWriter writer = zygoteState.writer;
        final DataInputStream inputStream = zygoteState.inputStream;
        writer.write(Integer.toString(args.size()));
        writer.newLine();
        for (int i = 0; i < sz; i++) {
            String arg = args.get(i);
            writer.write(arg);
            writer.newLine();
        }
        writer.flush();
        // Should there be a timeout on this?
        ProcessStartResult result = new ProcessStartResult();
        // Always read the entire result from the input stream to avoid leaving
        // bytes in the stream for future process starts to accidentally stumble
        // upon.
        // 等待 Socket 服务端(即 Zygote 进程)返回创建的进程的 pid
        result.pid = inputStream.readInt();
        result.usingWrapper = inputStream.readBoolean();
        if (result.pid < 0) {
            throw new ZygoteStartFailedEx("fork() failed");
        }
        return result;
    } catch (IOException ex) {
        zygoteState.close();
        throw new ZygoteStartFailedEx(ex);
    }
}

具体的进程创建不展开了(可以参阅:理解Android进程创建流程),需要知道的是,进程创建后,会根据我们之前传递的 ”android.app.ActivityThread” 字符串,反射出该对象,并执行其 main() 方法,而执行 main() 方法的线程即为 UI 线程,或者说是主线程

接着是关于 ActivityThread.main()

public static void main(String[] args) {
    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
    ...
    // 设置进程的名称
    Process.setArgV0("<pre-initialized>");
    // 初始化当前线程的 Looper,而当前线程即主线程
    Looper.prepareMainLooper();
    // 实例化 ActivityThread,即在主线程中实例化的
    ActivityThread thread = new ActivityThread();
    // 进行绑定
    thread.attach(false);
    if (sMainThreadHandler == null) {
        // 将 ActivityThread 实例对应的 handler 赋值给 sMainThreadHandler
        // 该 handler 会在 ActivityThread 实例化的时候初始化
        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");
}

在最开始说过,ActivityThread 并非传统意义上的 Thread(即线程),其并没有继承自 Thread,且从上面的源码可以看到,它是在 main() 方法中初始化的,只是主线程中的一个对象,而不是所谓的主线程,因而严格的来说,主线程指 main() 方法运行的线程。

main() 方法中,会执行 ActivityThread#attach() 方法:

// 此时传入的 system == false
private void attach(boolean system) {
    sCurrentActivityThread = this;
    mSystemThread = system;
    if (!system) {
        ViewRootImpl.addFirstDrawHandler(new Runnable() {
            @Override
            public void run() {
                ensureJitEnabled();
            }
        });
        android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                                UserHandle.myUserId());
        RuntimeInit.setApplicationObject(mAppThread.asBinder());
        // 得到 AMS 的 binder 代理对象(ActivityManagerProxy 类型)
        final IActivityManager mgr = ActivityManagerNative.getDefault();
        try {
        	// mAppThread 为 ApplicationThread 类型,实际上也是 Binder 对象,
        	// 是在 ActivityThread 初始化的时候被实例化的。
            mgr.attachApplication(mAppThread);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
        ...
    } else {
        ...
    }
    ...
}

attach() 中,会通过 AMS 对应的 binder 代理对象,调用远程 AMS 中的 attachApplication() 方法,并且将 ActivityThread 持有的 mAppThread(ApplicationThread 类型的 Binder 对象)传递过去。具体过程如下:

// mgr.attachApplication(mAppThread) 实际上会调用 ActivityManagerProxy#attachApplication
public void attachApplication(IApplicationThread app) throws RemoteException
{
    Parcel data = Parcel.obtain();
    Parcel reply = Parcel.obtain();
    data.writeInterfaceToken(IActivityManager.descriptor);
    data.writeStrongBinder(app.asBinder());
    // 通过 binder 引用切换到 ActivityManagerNative#transact()
    mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
    reply.readException();
    data.recycle();
    reply.recycle();
}

// ActivityManagerNative.java
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
        throws RemoteException {
    case ATTACH_APPLICATION_TRANSACTION: {
        data.enforceInterface(IActivityManager.descriptor);
        // 此处的 app 即从前面的 ActivityThread#attch() 中传递过来的 ApplicationThread 包装成的
        // binder 代理对象, ApplicationThreadProxy 实例,
        // 通过该代理对象,就可以实现与新建进程的通信
        IApplicationThread app = ApplicationThreadNative.asInterface(
                data.readStrongBinder());
        if (app != null) {
        	// 即调用该方法在其子类 ActivityManagerService 的具体实现
            attachApplication(app);
        }
        reply.writeNoException();
        return true;
    }
}

// ActivityManagerService.java
@Override
public final void attachApplication(IApplicationThread thread) {
    synchronized (this) {
    	// 得到调用者的 pid(即之前创建的进程的)
        int callingPid = Binder.getCallingPid();
        final long origId = Binder.clearCallingIdentity();
        attachApplicationLocked(thread, callingPid);
        Binder.restoreCallingIdentity(origId);
    }
}

private final boolean attachApplicationLocked(IApplicationThread thread,
        int pid) {
    // Find the application record that is being attached...  either via
    // the pid if we are running in multiple processes, or just pull the
    // next app record if we are emulating process with anonymous threads.
    ProcessRecord app;
    // 根据传递之前新建进程的 pid 获取 AMS 中对应的 ProcessRecord 实例,
    // 而该 ProcessRecord 实例即创建新进程之前在 startProcessLocked() 中生成的,
    // 并且该实例会根据 pid 保存到 mPidsSelfLocked 中。
    // 因此在这里能够实现根据目标 pid 查找对应的 ProcessRecord 实例
    if (pid != MY_PID && pid >= 0) {
        synchronized (mPidsSelfLocked) {
            app = mPidsSelfLocked.get(pid);
        }
    } else {
        app = null;
    }
    // 如果没有获取到对应的 ProcessRecord 实例,则会退出进程
    if (app == null) {
        ...
        if (pid > 0 && pid != MY_PID) {
            Process.killProcessQuiet(pid);
            //TODO: killProcessGroup(app.info.uid, pid);
        } else {
            try {
                thread.scheduleExit();
            } catch (Exception e) {}
        }
        return false;
    }
    ...
    // 将新建进程传递过来的 thread 赋值给 ProcessRecord#thread
    app.makeActive(thread, mProcessStats);
    ...
    try {
        ...
        // 获取对应的 appInfo
        ApplicationInfo appInfo = app.instrumentationInfo != null
                ? app.instrumentationInfo : app.info;
        app.compat = compatibilityInfoForPackageLocked(appInfo);
        if (profileFd != null) {
            profileFd = profileFd.dup();
        }
        ProfilerInfo profilerInfo = profileFile == null ? null
                : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
                
        // 1、利用新建进程的 binder 代理对象将需要的数据绑定到新建进程中
        thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
                profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
                app.instrumentationUiAutomationConnection, testMode,
                mBinderTransactionTrackingEnabled, enableTrackAllocation,
                isRestrictedBackupMode || !normalMode, app.persistent,
                new Configuration(mConfiguration), app.compat,
                getCommonServicesLocked(app.isolated),
                mCoreSettingsObserver.getCoreSettingsLocked());
        updateLruProcessLocked(app, false, null);
        app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
    } catch (Exception e) {
       	...
    }
    ...
    // See if the top visible activity is waiting to run in this process...
    if (normalMode) {
        try {
        	// 2、在执行完 thread.bindApplication() 之后就会调用 
        	// ActivityStackSupervisor#attachApplicationLocked(app)
            if (mStackSupervisor.attachApplicationLocked(app)) {
                didSomething = true;
            }
        } catch (Exception e) {
            Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
            badApp = true;
        }
    }
    ...
    return true;
}

AMS#attachApplicationLocked() 中,会根据新建进程的 pid 或者存储在 AMS 中的 ProcessRecord 实例,然后将从新建进程中传递过来的 thread 赋值给 ProcessRecord 实例的成员变量 thread。

1、thread.bindApplication()

调用 thread.bindApplication() 实际上是调用 ApplicationThreadProxy#bindApplication(),然后通过 Binder 机制调用新建进程中的 ApplicationThread#bindApplication()(调用该方法的时候处于 binder 线程池中的某一线程中,而非主线程,具体原因参考 Binder 机制的实现原理):

public final void bindApplication(...) {
    if (services != null) {
        // Setup the service cache in the ServiceManager
        ServiceManager.initServiceCache(services);
    }
    setCoreSettings(coreSettings);
    AppBindData data = new AppBindData();
    // 将传递进来的各种数据设置到 data 中
    ...
    // ApplicationThread 为 ActivityThread 的内部类,
    // sendMessage() 为 ActivityThread 的成员方法
    sendMessage(H.BIND_APPLICATION, data);
}

可以看到,这里会调用 sendMessage(),即通过主线程的 handler (从 binder 线程)切换到主线程中。

在主线程的 Handler#handleMessage() 中有如下逻辑:

case BIND_APPLICATION:
    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
    AppBindData data = (AppBindData)msg.obj;
    handleBindApplication(data);
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    break;

进而调用 ActivityThread#handleBindApplication()

private void handleBindApplication(AppBindData data) {
    ...
    mBoundApplication = data;
    ...
    // send up app name; do this *before* waiting for debugger
    // 设置进程的名字,即进程名是在进程真正创建以后的 BIND_APPLICATION 过程中才取名
    Process.setArgV0(data.processName);
    android.ddm.DdmHandleAppName.setAppName(data.processName,
                                            UserHandle.myUserId());
    ...
    // 得到 LoadedApk 对象实例并赋值给 data.info 
    // LoadedApk 对象是 APK 文件在内存中的表示。 Apk 文件的相关信息,诸如 Apk 文件的代码和资源,
    // 甚至代码里面的 Activity,Service 等组件的信息我们都可以通过此对象获取
    data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
    ...
    // 
    final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
    updateLocaleListFromAppContext(appContext,
            mResourcesManager.getConfiguration().getLocales());
    ...
    // Continue loading instrumentation.
    // 加载 mInstrumentation
    if (ii != null) {
        final ApplicationInfo instrApp = new ApplicationInfo();
        ii.copyTo(instrApp);
        instrApp.initForUser(UserHandle.myUserId());
        final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
                appContext.getClassLoader(), false, true, false);
        final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
        try {
            final ClassLoader cl = instrContext.getClassLoader();
            mInstrumentation = (Instrumentation)
                cl.loadClass(data.instrumentationName.getClassName()).newInstance();
        } catch (Exception e) {
            throw new RuntimeException(
                "Unable to instantiate instrumentation "
                + data.instrumentationName + ": " + e.toString(), e);
        }
        final ComponentName component = new ComponentName(ii.packageName, ii.name);
        mInstrumentation.init(this, instrContext, appContext, component,
                data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
        ..
    } else {
        mInstrumentation = new Instrumentation();
    }
    ...
    try {
        // If the app is being launched for full backup or restore, bring it up in
        // a restricted environment with the base application class.
        // 通过 data.info 得到应用的 Application 实例。
        // 在 makeApplication() 方法中,如果 Application 实例已经存在,则直接返回;
        // 否则会通过反射生成新的实例对象。
        // 且在 makeApplication() 方法中,传入的第三个参数为 Instrumentation 类型,如果不为空,
        // 且是 application 是新建的,则会调用 Instrumentation#callApplicationOnCreate() 来
        // 调用 application 的 onCreate() 方法
        Application app = data.info.makeApplication(data.restrictedBackupMode, null);
        // 赋值给 ActivityThread#mInitialApplication()
        mInitialApplication = app;
        ...
        try {
            mInstrumentation.onCreate(data.instrumentationArgs);
        }
        catch (Exception e) {...}
        try {
         	// 调用 Application 的 onCreate() 方法
            mInstrumentation.callApplicationOnCreate(app);
        } catch (Exception e) {...}
    } finally {
        StrictMode.setThreadPolicy(savedPolicy);
    }
}

handleBindApplication() 方法主要作用就是:

1、为 ActivityThread#mBoundApplication 赋值
2、设置应用进程的名字
3、得到 LoadedApk 实例对象并赋值给 ActivityThread#mBoundApplication.info
4、实例化 ActivityThread#mInstrumentation
5、得到应用的 Application 实例对象,并赋值给 ActivityThread#mInitialApplication
6、调用 Application 的 onCreate() 方法

2、mStackSupervisor.attachApplicationLocked(app)

ActivityManagerService#attachApplicationLocked() 中执行完 thread.bindApplication() 之后,会调用 ActivittyStackSupervisor#attachApplicationLocked()

// ActivityStackSupervisor.java
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
    final String processName = app.processName;
    boolean didSomething = false;
    for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
        ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
            final ActivityStack stack = stacks.get(stackNdx);
            if (!isFocusedStack(stack)) {
                continue;
            }
            ActivityRecord hr = stack.topRunningActivityLocked();
            if (hr != null) {
                if (hr.app == null && app.uid == hr.info.applicationInfo.uid
                        && processName.equals(hr.processName)) {
                    try {
                    	// 调用 realStartActivityLocked() 方法
                        if (realStartActivityLocked(hr, app, true, true)) {
                            didSomething = true;
                        }
                    } catch (RemoteException e) {...}
                }
            }
        }
    }
    if (!didSomething) {
        ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
    }
    return didSomething;
}

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
        boolean andResume, boolean checkConfig) throws RemoteException {
    ...
    try {
        ...
        // 通过要启动的根 Activity 所在的 ProcessRecord 实例的 thread 成员变量
        // (ApplicationThreadProxy 类型,为 binder 代理对象)
        // 来切换到根 Activity 对应的 app 进程中,启动根 Activity
        app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
                new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,
                task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
                newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
        
    } catch (RemoteException e) {...}
    ...
    return true;
}

realStartActivityLocked() 方法中可知,基于 Binder 机制,通过 app.thread 会切换到根 Activity 对应的进程中,即最终会来到 ActivityThread#ApplicationThread#scheduleLaunchActivity() 方法中:

@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) {
    ...
    // 将要启动的 Activity 封装成 ActivityClientRecord 实例 r
    ActivityClientRecord r = new ActivityClientRecord();
    // 为 r 的成员变量赋值
    ...
    // 切换到主线程中,因为当前所处方法是在 AMS 中基 Binder 机制而调用的,
    // 此时(被调用时)处于目标启动 Activity 的应用进程的 binder 线程池中
    sendMessage(H.LAUNCH_ACTIVITY, r);
}

// ActivityThread # H
public void handleMessage(Message msg) {
    switch (msg.what) {
        case LAUNCH_ACTIVITY: {
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
            // 传递过来的要启动的 Activity 对应的 ActivityClientRecord 实例
            final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
            // 通过 getPackageInfoNoCheck() 方法获得 LoadedApk 实例赋值给 r.packageInfo
            // 应用程序要启动 Activity 时需要将该 Activity 所属的 APK 加载进来,
            // 而 LoadedApk 就是用来描述已加载的 APK 文件的
            r.packageInfo = getPackageInfoNoCheck(
                    r.activityInfo.applicationInfo, r.compatInfo);
            handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        } break;
        ...
    }
}

之后会进一步调用 ActivityThread#handleLaunchActivity()

// ActivityThread.java
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
    ...
    // 启动 Activity,此时(LAUNCH_ACTIVITY)传递过来的 customIntent 为 null
    // 在该方法中会通过类加载机制实例化一个 Activity
    Activity a = performLaunchActivity(r, customIntent);
    if (a != null) {
        r.createdConfig = new Configuration(mConfiguration);
        reportSizeConfigurations(r);
        Bundle oldState = r.state;
        // 间接调用 Activity#onResume()
        handleResumeActivity(r.token, false, r.isForward,
                !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
        ...
    } else {
        ...
    }
}

在启动根 Activity 之时,会先通过 ActivityThread#performLaunchActivity() 方法创建对应的 Activity 实例,且在ActivityThread#performLaunchActivity() 方法中,会调用 Activity 的 onCreate()、onStart()

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    // 获取 ActivityInfo
    // ActivityInfo 用于存储 AndroidManifests 中设置的 Activity 和 Receiver 节点信息,
    // 如 Activity 的 theme 和 launchMode
    ActivityInfo aInfo = r.activityInfo;
    if (r.packageInfo == null) {
        // 获取 LoadedApk
        r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                Context.CONTEXT_INCLUDE_CODE);
    }
    // 获取要启动 Activity 的 ComponentName 实例,该实例保存类了该 Activity 的包名和类名
    ComponentName component = r.intent.getComponent();
    ...
    Activity activity = null;
    try {
        java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
        // 使用类加载器创建要启动的 Activity 实例
        activity = mInstrumentation.newActivity(
                cl, component.getClassName(), r.intent);
        ...
    } catch (Exception e) {...}
    try {
        // 获取 Application 实例(在 ActivityThread#handleBindApplication() 中说过)
        // r.packageInfo 即 LoadedApk 实例
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);
        ...
        if (activity != null) {
            // 创建要启动的 Activity 对应的上下文(Context)
            Context appContext = createBaseContextForActivity(r, activity);
            ...
            // 通过 Activity#attch() 方法初始化 activity 的成员变量,
            // 在该方法中会创建 Window(PhoneWindow) 对象与该 Activity 关联
            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);
            ...
            // 调用 Instrumentation#callActivityOnCreate() 来启动 Activity
            // 在该方法中就会调用 Activity#onCreate() 方法(即实现了根 Activity 的启动,即应用程序的启动)
            if (r.isPersistable()) {
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
            } else {
                mInstrumentation.callActivityOnCreate(activity, r.state);
            }
            ...
            r.activity = activity;
            r.stopped = true;
            if (!r.activity.mFinished) {
            	// 实现调用 Activity#onStart()
                activity.performStart();
                r.stopped = false;
            }
            ...
        }
        r.paused = true;
        mActivities.put(r.token, r);
    } catch (SuperNotCalledException e) {...}
    return activity;
}

performLaunchActivity() 方法主要进行了如下操作:

1、通过反射机制得到 Activity 实例
2、间接调用 Activity#onCreate()
3、间接调用 Activity#onStart()

ActivityThread#performLaunchActivity() 执行完后,会通过 ActivityThread#handleResumeActivity() 间接调用 Activity#onResume()

这样,就完了对于 Activity 的 onCreate()、onStart()、onResume() 这三个生命周期的方法的调用。

关于调用 ActivityThread.main() 的简易流程图如下:
在这里插入图片描述

至此,对于从创建启动根 Activity 对应的进程,接着启动根 Activity 这一过程,就算完成了。

简单的流程总结,摘抄自:Android 7.1.2(Android N) Activity启动流程分析

1、点击桌面App图标,Launcher进程采用Binder IPC向system_server进程发起startActivity请求;
2、system_server进程接收到请求后,向zygote进程发送创建进程的请求;
3、Zygote进程fork出新的子进程,即App进程;
4、App进程,通过Binder IPC向sytem_server进程发起attachApplication请求;
5、system_server进程在收到请求后,进行一系列准备工作后,再通过binder IPC向App进程发送scheduleLaunchActivity请求;
6、App进程的binder线程(ApplicationThread)在收到请求后,通过handler向主线程发送LAUNCH_ACTIVITY消息;
7、主线程在收到Message后,通过发射机制创建目标Activity,并回调Activity.onCreate()等方法。

到此,App 便正式启动,开始进入 Activity 生命周期,执行完 onCreate/onStart/onResume 方法,UI 渲染结束后便可以看到 App 的主界面。


补充:

1、有关 Activity#mToken

需要说明的是,这里说的 Activity#mToken 是 Launcher Activity 的。

mToken 是在何时被赋值的呢,是在 ActivityThread#performLaunchActivity() 中,通过在 Activity#attach() 中被赋值的,传递的第三个参数 r.token 会被赋值给 mToken。

activity.attach(appContext, this, getInstrumentation(), r.token,...);

而 r 即 ActivityClientRecord,而 r 是在 ApplicationThread#scheduleLaunchActivity() 中被初始化的,r.token 在初始化时被赋值。

而该值是在 ActivityStackSupervisor#realStartActivityLocked() 中调用

app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, ...) 

时传递的(传递的第二个参数),此时的 r 为 ActivityRecord,所以即 ActivityRecord#appToken,而这里的 r 又是在 ActivityStarter#startActivityLocked() 被 new 出来的,在其构造方法中,会为 appToken 赋值:

ActivityRecord(ActivityManagerService _service, ProcessRecord _caller,
        int _launchedFromUid, String _launchedFromPackage, Intent _intent, String _resolvedType,
        ActivityInfo aInfo, Configuration _configuration,
        ActivityRecord _resultTo, String _resultWho, int _reqCode,
        boolean _componentSpecified, boolean _rootVoiceInteraction,
        ActivityStackSupervisor supervisor,
        ActivityContainer container, ActivityOptions options, ActivityRecord sourceRecord) {
    service = _service;
    appToken = new Token(this, service);
    ...
}

而其作用,可以参阅:
1、 深入理解Activity——Token之旅
2、AMS_WMS_APP 中Token惟一性

2、AndroidManifest.xml 中的 activity 标签是什么时候被读取的?

是在生成 ActivityInfo 的时候读取的,具体的是在 ActivityStarter#startActivityMayWait() 方法中:

首先会得到 ResolveInfo

// 通过 PackageManager 解析需要启动的 intent 信息
ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);

在这里插入图片描述

然后再得到 ActivityInfo

// Collect information about the target of the Intent.
// 得到 itent 对应的 ActivityInfo
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);

在这里插入图片描述

3、如果应用处于后台且活着,此时点击 Launcher 启动对应的根 Activity 又是怎样的

先声明,对于这一个问题,暂时没有时间深究,不过,我猜测这个时候就和 Stack、Task 有关了,因为此时应用处于后台,且没有因内存等原因被回收的话,此时点击桌面的应用图标,则会把该应用切换到前台,而不是走传统的启动根 Activity 的流程。

4、有关 Launcher Activity 的声明周期的变化,即什么时候执行其 onPause()、onStop() 方法

参考文章:从源码角度看Activity生命周期

(1) 关于 onPause() 的执行

在第二部分中,有调用 ActivityStack#resumeTopActivityInnerLocked()

// ActivityStack.java
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
	...
    if (mResumedActivity != null) {
        if (DEBUG_STATES) Slog.d(TAG_STATES,
                "resumeTopActivityLocked: Pausing " + mResumedActivity);
        pausing |= startPausingLocked(userLeaving, false, next, dontWaitForPause);
    }
    ...
}

final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
            ActivityRecord resuming, boolean dontWait) {
	...
	ActivityRecord prev = mResumedActivity;
	...
    if (prev.app != null && prev.app.thread != null) {
        try {
            ...
            // finishing 表示 activity 是否在 pending finish list 中
            // 对于 Launcher Activity,可以推断 finishing 为 false
            prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
                    userLeaving, prev.configChangeFlags, dontWait);
        } catch (Exception e) {
            ...
        }
    }
    ...
}

prev.app 即 ProcessRecord,ProcessRecord#thread 即 app 进程在 AMS 中关于 ApplicationThread 的代理对象。

这里 prev 即 Launcher Activity 的。通过 prev.app.thread.schedulePauseActivity(),最终会调用:

// ActivityThread # ApplicationThread
public final void schedulePauseActivity(IBinder token, boolean finished,
        boolean userLeaving, int configChanges, boolean dontReport) {
    int seq = getLifecycleSeq();
    if (DEBUG_ORDER) Slog.d(TAG, "pauseActivity " + ActivityThread.this
            + " operation received seq: " + seq);
    // finished == false
    // 因此对应 PAUSE_ACTIVITY
    sendMessage(
            finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
            token,
            (userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0),
            configChanges,
            seq);
}

对于 PAUSE_ACTIVITY 有:

case PAUSE_ACTIVITY: {
    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
    SomeArgs args = (SomeArgs) msg.obj;
    handlePauseActivity((IBinder) args.arg1, false,
            (args.argi1 & USER_LEAVING) != 0, args.argi2,
            (args.argi1 & DONT_REPORT) != 0, args.argi3);
    maybeSnapshot();
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;

// ActivityThread.java
private void handlePauseActivity(IBinder token, boolean finished,
        boolean userLeaving, int configChanges, boolean dontReport, int seq) {
    ...
    if (r != null) {
        ...
        performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity");
        ...

		// Tell the activity manager we have paused.
		// 等执行完 Activity#onPause() 之后,告诉 AMS 当前 Activity 已经 paused 了
        if (!dontReport) {
            try {
                ActivityManagerNative.getDefault().activityPaused(token);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }
    }
}

final Bundle performPauseActivity(IBinder token, boolean finished,
        boolean saveState, String reason) {
    // token 即之前 AMS 进程中 ActivityStack#startPausingLocked() 传递过来的
    // ActivityRecord#appToken,通过其可以找到 app 进程中对应的 ActivityClientRecord 实例
    ActivityClientRecord r = mActivities.get(token);
    return r != null ? performPauseActivity(r, finished, saveState, reason) : null;
}

final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
            boolean saveState, String reason) {
	...
	performPauseActivityIfNeeded(r, reason);
	...
}

private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
    if (r.paused) {
        // You are already paused silly...
        return;
    }
    try {
        r.activity.mCalled = false;
        mInstrumentation.callActivityOnPause(r.activity);
        ...
    } catch (...) {...}   
    r.paused = true;
}

Instrumentation#callActivityOnPause() 最终会调用 Activity#onPause()

根据 Launcher Activity 的 onPause() 最终的调用时机可知,该方法调用先于根 Activity 的 onCreate() 的调用,这也就符合,“Activity A 中启动 Activity B 时” 生命周期变化为:

 A.onPause() -> B.onCreate() -> B.onStart() -> B.onResume() -> A.onStop()

这里有一个需要注意的点,就是调用 A.onPause() 的时候,最开始是从 AMS 中发起的,即在 AMS 中基于 Binder 机制切换到了应用的 Binder 线程池,然后进一步切换到应用的主线程中执行的,这里切换到应用进程主线程后实际上对于 AMS 中接下来的逻辑来说,实际上是异步的。(但是对于从 AMS 切换到应用进程的 Binder 线程池中的线程,这一段是同步的,因为 Binder 机制实现跨进程是基于阻塞式的,此时 AMS 进程中的逻辑会被挂起)

因此是如果保证等到 A.onPause() 执行完,才去执行 B.onCreate() 的呢?实际上,在 ActivityThread#handlePauseActivity() 中,当执行完 performPauseActivity() 之后,正常情况下会执行:

ActivityManagerNative.getDefault().activityPaused(token);
// ActivityManagerService.java
@Override
public final void activityPaused(IBinder token) {
    final long origId = Binder.clearCallingIdentity();
    synchronized(this) {
        ActivityStack stack = ActivityRecord.getStackLocked(token);
        if (stack != null) {
            stack.activityPausedLocked(token, false);
        }
    }
    Binder.restoreCallingIdentity(origId);
}

即执行完 onPause() 之后返回来通知 AMS,目标 Activity 已经执行完 onPause() 了。

当然,具体如何实现异步等待的,暂不深究,但是可以猜测,当在 AMS 中基于 Binder 机制调用目标 Activity 的 onPause() 的时候,会通过某种方法,等待目标 Activity 执行完 onPause() 并回调 AMS 的 activityPaused() 之后,才会执行之后的逻辑。

实际上,在 AMS 中类似的还有 :activityResumed()、activityStopped()、activityDestroyed()

(2) 关于 onStop() 的执行

在前面说过,ActivityThread#handleResumeActivity() 中:

// ActivityThread.java

final void handleResumeActivity(IBinder token,
            boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
	...
	// 在该方法中会间接调用 Activity#onResume()
	r = performResumeActivity(token, clearHide, reason);
	if (r != null) {
		...
        if (!r.onlyLocalRequest) {
            r.nextIdle = mNewActivities;
            mNewActivities = r;
            if (localLOGV) Slog.v(
                TAG, "Scheduling idle handler for " + r);
            // 在主线程中添加一个 IdleHandler
            Looper.myQueue().addIdleHandler(new Idler());
        }
	}
}

private class Idler implements MessageQueue.IdleHandler {
    @Override
    public final boolean queueIdle() {
        ActivityClientRecord a = mNewActivities;
        ...
        if (a != null) {
            mNewActivities = null;
            IActivityManager am = ActivityManagerNative.getDefault();
            ActivityClientRecord prev;
            do {
                if (localLOGV) Slog.v(
                    TAG, "Reporting idle of " + a +
                    " finished=" +
                    (a.activity != null && a.activity.mFinished));
                if (a.activity != null && !a.activity.mFinished) {
                    try {
                        am.activityIdle(a.token, a.createdConfig, stopProfiling);
                        a.createdConfig = null;
                    } catch (RemoteException ex) {
                        throw ex.rethrowFromSystemServer();
                    }
                }
                prev = a;
                a = a.nextIdle;
                prev.nextIdle = null;
            } while (a != null);
        }
        ...
        return false;
    }
}

ActivityManagerService#activityIdle()

// ActivityManagerService.java
public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
    final long origId = Binder.clearCallingIdentity();
    synchronized (this) {
        ActivityStack stack = ActivityRecord.getStackLocked(token);
        if (stack != null) {
            ActivityRecord r =
                    mStackSupervisor.activityIdleInternalLocked(token, false, config);
            if (stopProfiling) {
                if ((mProfileProc == r.app) && (mProfileFd != null)) {
                    try {
                        mProfileFd.close();
                    } catch (IOException e) {
                    }
                    clearProfilerLocked();
                }
            }
        }
    }
    Binder.restoreCallingIdentity(origId);
}

activityIdle() 中会通过 StackSupervisor#activityIdleInternalLocked(), 根据实际情况,对栈中的 Activity 进行 stop 处理,或者 destroy 处理(在 destroy 的时候包含 stop 处理。)(具体源码调用过程不展开)

因此,对于 Activity#onStop(),实际上是在栈定的 Activity 执行了 onResume() 之后,利用其应用进程的主线程来处理 IdleHandler,来间通过 AMS Binder 代理对象实现调用栈顶下面的 Activity 的 onStop() 方法。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值