Android 6.0 AMS分析的第二条线:以Launcher启动一个Activity为例,分析应用进程的创建、Activity的启动,以及他们和AMS之间的交互等知识;

这篇是通过Launcher启动一个activity的过程,先以一张开头。

《Android 6.0 AMS分析的第二条线:以Launcher启动一个Activity为例,分析应用进程的创建、Activity的启动,以及他们和AMS之间的交互等知识;》

Step 1. Launcher.startActivitySafely

在Android系统中,应用程序是由Launcher启动起来的,其实,Launcher本身也是一个应用程序,其它的应用程序安装后,就会Launcher的界面上出现一个相应的图标,点击这个图标时,Launcher就会对应的应用程序启动起来。
Launcher.java (packages\apps\launcher3\src\com\android\launcher3)

    public boolean startActivitySafely(View v, Intent intent, Object tag) {
        boolean success = false;
        if (mIsSafeModeEnabled && !Utilities.isSystemApp(this, intent)) {
            Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();
            return false;
        }
        try {
            success = startActivity(v, intent, tag);
        } catch (ActivityNotFoundException e) {
            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
            Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);
        }
        return success;
    }

Step 2. Activity.startActivity

在Step 1中,我们看到,Launcher继承于Activity类,而Activity类实现了startActivity函数,因此,这里就调用了Activity.startActivity函数
Activity.java (frameworks\base\core\java\android\app)

    @Override
    public void startActivity(Intent intent, @Nullable Bundle options) {
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            // 这个函数实现很简单,它调用startActivityForResult来进一步处理,第二个参数传入-1表示不需要这个Actvity结束后的返回结果。
            startActivityForResult(intent, -1);
        }
    }

Step 3. Activity.startActivityForResult

    public void startActivityForResult(
            String who, Intent intent, int requestCode, @Nullable Bundle options) {
        Uri referrer = onProvideReferrer();
        if (referrer != null) {
            intent.putExtra(Intent.EXTRA_REFERRER, referrer);
        }
        Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                        this, mMainThread.getApplicationThread(), mToken, who,
                        intent, requestCode, options);
        if (ar != null) {
            mMainThread.sendActivityResult(
                    mToken, who, requestCode,
                    ar.getResultCode(), ar.getResultData());
        }
        cancelInputsAndStartExitTransition(options);
    }

1、这里的mInstrumentation是Activity类的成员变量,它的类型是Intrumentation,定义在frameworks/base/core/java/android/app/Instrumentation.java文件中,它用来监控应用程序和系统的交互。
2、这里的mMainThread也是Activity类的成员变量,它的类型是ActivityThread,它代表的是应用程序的主线程,我们在Android系统在新进程中启动自定义服务过程(startService)的原理分析一文中已经介绍过了。这里通过mMainThread.getApplicationThread获得它里面的ApplicationThread成员变量,它是一个Binder对象,后面我们会看到,ActivityManagerService会使用它来和ActivityThread来进行进程间通信。这里我们需注意的是,这里的mMainThread代表的是Launcher应用程序运行的进程。
3、这里的mToken也是Activity类的成员变量,它是一个Binder对象的远程接口。

Step 4. Instrumentation.execStartActivity

    public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, String target,
            Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        if (mActivityMonitors != null) {
        ......
        }
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess();
            // ActivityManagerNative.getDefault返回ActivityManagerService的远程接口,即ActivityManagerProxy接口
            int result = ActivityManagerNative.getDefault()
                    .startActivity(whoThread, who.getBasePackageName(), intent,
                            /* 这里的intent.resolveTypeIfNeeded返回这个intent的MIME类型,在这个例子中, 没有AndroidManifest.xml设置MainActivity的MIME类型,因此,这里返回null。 */
                            intent.resolveTypeIfNeeded(who.getContentResolver()),
                            token, target, requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

Step 5. ActivityManagerProxy.startActivity

ActivityManagerNative.java (frameworks\base\core\java\android\app)

    public int startActivity(......) throws RemoteException {
        /*
        参数resolvedType、resultWho均为null;
        参数caller为ApplicationThread类型的Binder实体;
        参数resultTo为一个Binder实体的远程接口,我们先不关注它;
        参数grantedMode为0,我们也先不关注它;
        参数requestCode为-1;
        参数onlyIfNeeded和debug均空false。
         */
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
        data.writeString(callingPackage);
        intent.writeToParcel(data, 0);
        data.writeString(resolvedType);
        data.writeStrongBinder(resultTo);
        data.writeString(resultWho);
        data.writeInt(requestCode);
        data.writeInt(startFlags);
        return result;
    }

Step 6. ActivityManagerService.startActivity

这里只是简单地将操作转发给成员变量mStackSupervisor的startActivityMayWait函数,这里的mMainStack的类型为ActivityStackSupervisor。

    @Override
    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
        enforceNotIsolatedCaller("startActivity");
        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
                false, ALLOW_FULL_ONLY, "startActivity", null);
        // TODO: Switch to user app stacks here.
        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
                profilerInfo, null, null, options, false, userId, null, null);
    }

Step 7. ActivityStackSupervisor.startActivityMayWait

一、ActivityStackSupervisor.java (frameworks\base\services\core\java\com\android\server\am)
一)、startActivityMayWait函数的目标是启动com.dfp.test.TestActivity,假设系统之前没有启动过该Activity,
本例最终的结果将是:
1、由于在am中设置了FLAG_ACTIVITY_NEW_TASK标志,因此除了会创建一个新的ActivityRecord外,
还会新建一个TaskR额cord
2、还需要启动一个新的应用进程以加载并运行com.dfp.test.TestActivity的一个实例
3、如果TestActivity不是home,还需要停止当前正在显示的Activity
二)、将这个函数分三部分进行介绍
第一部分:
1、首先需要通过PKMS查询匹配该Intent的ActivityInfo
2、处理FLAG_CANT_SAVE_STATE的情况,但系统目前不支持此情况
3、获取调用者的pid和uid,由于本例的caller为null,故所得到的pid和uid均为am所在进程的uid和pid。
第二部分:启动核心函数startActivityLocked
第三部分:根据返回值做一些处理,那么res返回成功后(即res==IActivityManager.START_SUCCESS的时候)
后为何还需要等待? 这是因为目标Activity要运行在一个新的应用进程中,就必须等待那个应用进程正常启动
并处理相关的请求。

   final int startActivityMayWait(......) {
        // 第一部分:本例已经指明了component,这样可以省去为Intent匹配搜索之苦
        boolean componentSpecified = intent.getComponent() != null;
        // 创建一个新的Intent,防止客户传入的Intent被修改
        intent = new Intent(intent);
        // 查询满足条件的ActivityInfo,在resolveActivity内部和PKMS交互,
        // 参数intent的内容进行解析,得到MainActivity的相关信息,保存在aInfo变量中
        ActivityInfo aInfo =
                resolveActivity(intent, resolvedType, startFlags, profilerInfo, userId);
        //
        ActivityContainer container = (ActivityContainer) iContainer;
        synchronized (mService) {
            if (container != null && container.mParentActivity != null &&
                    container.mParentActivity.state != RESUMED) {
                // Cannot start a child activity if the parent is not resumed.
                return ActivityManager.START_CANCELED;
            }
            final int realCallingPid = Binder.getCallingPid();
            final int realCallingUid = Binder.getCallingUid();
            int callingPid;
            if (callingUid >= 0) {
                callingPid = -1;
            } else if (caller == null) { //本例中,caller为null
                callingPid = realCallingPid; // 取出调用进程的pid
                callingUid = realCallingUid;// 取出调用进程的uid
            } else {
                callingPid = callingUid = -1;
            }
            final ActivityStack stack;
            if (container == null || container.mStack.isOnHomeDisplay()) {
                stack = mFocusedStack;
            } else {
                stack = container.mStack;
            }
            // 在本例中config为null
            stack.mConfigWillChange = config != null && mService.mConfiguration.diff(config) != 0;
            final long origId = Binder.clearCallingIdentity();
            if (aInfo != null &&
                    (aInfo.applicationInfo.privateFlags
                            & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
                ......
            }
            // 第二部分:调用此函数启动Activity,将返回值保存到res
            int res = startActivityLocked(caller, intent, resolvedType, aInfo,
                    voiceSession, voiceInteractor, resultTo, resultWho,
                    requestCode, callingPid, callingUid, callingPackage,
                    realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity,
                    componentSpecified, null, container, inTask);
            Binder.restoreCallingIdentity(origId);
            // 如果configuration发生变化,则调用AMS的updateConfigurationLocked进行处理
            if (stack.mConfigWillChange) {
                // If the caller also wants to switch to a new configuration,
                // do so now. This allows a clean switch, as we are waiting
                // for the current activity to pause (so we will not destroy
                // it), and have not yet started the next activity.
                mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
                        "updateConfiguration()");
                stack.mConfigWillChange = false;
                mService.updateConfigurationLocked(config, null, false, false);
            }
            if (outResult != null) {
                outResult.result = res; // 第三部分:设置启动结果
                if (res == ActivityManager.START_SUCCESS) {
                    // 该结果在mWaitingActivityLaunched中保存
                    mWaitingActivityLaunched.add(outResult);
                    do {
                        try {
                            mService.wait(); // 等待启动结果
                        } catch (InterruptedException e) {
                        }
                    } while (!outResult.timeout && outResult.who == null);
                } else if (res == ActivityManager.START_TASK_TO_FRONT) { // 处理START_TASK_TO_FRONT结果
                    ActivityRecord r = stack.topRunningActivityLocked(null);
                    if (r.nowVisible && r.state == RESUMED) {
                        outResult.timeout = false;
                        outResult.who = new ComponentName(r.info.packageName, r.info.name);
                        outResult.totalTime = 0;
                        outResult.thisTime = 0;
                    } else {
                        outResult.thisTime = SystemClock.uptimeMillis();
                        mWaitingActivityVisible.add(outResult);
                        do {
                            try {
                                mService.wait();
                            } catch (InterruptedException e) {
                            }
                        } while (!outResult.timeout && outResult.who == null);
                    }
                }
            }
            return res;
        }
    }

Step 8. ActivityStack.startActivityLocked二、startActivityLocked分析

一)、startActivityLocked是startActivityMayWait第二阶段的重点
它的主要工作包括:
1、处理sourceRecord及resultRecord。其中,sourceRecord表示发起本次请求的Activity,
resultRecord表示接收处理结果的Activity(启动一个Activity肯定需要它完成某项事情,
当目标Activity将事情成后,就需要告知请求者该事情的处理结果)。
在一般情况下,sourceRecord和resultRecord应指向同一个Activity。
2、处理app switch。 如果AMS当前禁止app switch,则只能把本次启动请求保存起来,
以待允许app switch时在处理。 从代码中可知,AMS在处理本次请求前,会先调用
doPendingActivityLaunchesLocked函数,在该函数内部将启动之前因系统禁止app switch
而保存的Pending请求。
3、将对应ActivityRecord移动到Task的顶部
4、调用startActivityUncheckedLocked处理本次Activity启动请求

    final int startActivityLocked(......) {
        int err = ActivityManager.START_SUCCESS;
        ProcessRecord callerApp = null;
        // 如果caller不为空,则需要从AMS中找到它的ProcessRecord。本例中的caller为null
        if (caller != null) {
                    // 从传进来的参数caller得到调用者的进程信息,并保存在callerApp变量中,这里就是Launcher应用程序的进程信息了
            callerApp = mService.getRecordForAppLocked(caller);
            // 其实就是想得到进程的pid和uid
            if (callerApp != null) {
                // 一定要保证调用进程的pid和uid正确
                callingPid = callerApp.pid;
                callingUid = callerApp.info.uid;
            } else { // 如果用进程没有在AMS中注册,则认为其实非法的
                err = ActivityManager.START_PERMISSION_DENIED;
            }
        }
        final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
        /* 下面两个变量很重要,sourceRecord用于描述启动目标Activity的那个Activity, resultRecord用于描述接收启动的结果的Activity,即,该Activity的onActivityResult 将被调用已通知启动结果 */
        ActivityRecord sourceRecord = null;
        ActivityRecord resultRecord = null;
        if (resultTo != null) {
 // 参数resultTo是Launcher这个Activity里面的一个Binder对象,通过它可以获得Launcher这个Activity的相关信息,保存在sourceRecord变量中。 
            sourceRecord = isInAnyStackLocked(resultTo);
            if (sourceRecord != null) {
                if (requestCode >= 0 && !sourceRecord.finishing) {
                    resultRecord = sourceRecord;
                }
            }
        }
        // 获取Intent设置的启动标志,他们是和Launch Mode 类似的小把戏
        final int launchFlags = intent.getFlags();
        if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
            /* 前面介绍的Launch Mode和Acitivity的启动有关,实际上还有一部分标志用于控制Activity启动结果的通知。 使用FLAG_ACTIVITY_FORWARD_RESULT前Activity必须先存在(sourceRecord != null) */
        }
        // 检查err值及Intent的情况
        if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
            // We couldn't find a class that can handle the given Intent.
            // That's the end of that!
            err = ActivityManager.START_INTENT_NOT_RESOLVED;
        }
        final ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
        // 如果err不为0,则调用sendActivityResultLocked返回错误
        if (err != ActivityManager.START_SUCCESS) {
            if (resultRecord != null) { // resultRecord接收启动结果
                resultStack.sendActivityResultLocked(-1,
                        resultRecord, resultWho, requestCode,
                        Activity.RESULT_CANCELED, null);
            }
            ActivityOptions.abort(options);
            return err;
        }
        boolean abort = false;
        // 权限检查
        final int startAnyPerm = mService.checkPermission(
                START_ANY_ACTIVITY, callingPid, callingUid);
        abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
                callingPid, resolvedType, aInfo.applicationInfo);
        /* 可为AMS设置一个IActivityController类型的监听,AMS有任何动静都会回调该监听 不过谁又有如此本事监听AMS? 在进行Monkey测试的时候,Monkey会设置该回调的对象。 这样,Monkey就能根据AMS放映的情况进行相应的处理*/
        if (mService.mController != null) {
            try {
                // The Intent we give to the watcher has the extra data
                // stripped off, since it can contain private information.
                Intent watchIntent = intent.cloneFilter();
                abort |= !mService.mController.activityStarting(watchIntent,
                        aInfo.applicationInfo.packageName);
            } catch (RemoteException e) {
                mService.mController = null;
            }
        }
        // 回调对象决定不启动该Activity,在进行monkey测试时,可设置黑名单,位于黑名单中的Activity将不能启动
        if (abort) {
            if (resultRecord != null) {
                resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
                        Activity.RESULT_CANCELED, null);
            }
            // We pretend to the caller that it was really started, but
            // they will just get a cancel result.
            ActivityOptions.abort(options);
            // 通知resultRecord
            return ActivityManager.START_SUCCESS;
        }
        // 创建一个ActivityRecord对象
        ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
                intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
                requestCode, componentSpecified, voiceSession != null, this, container, options);
        if (outActivity != null) {
            outActivity[0] = r;  // 保存到输入参数outActivity数组中
        }
        if (r.appTimeTracker == null && sourceRecord != null) {
            // If the caller didn't specify an explicit time tracker, we want to continue
            // tracking under any it has.
            r.appTimeTracker = sourceRecord.appTimeTracker;
        }
        final ActivityStack stack = mFocusedStack;
        // mResumedActivity 代表当前界面显示的Activity
        if (voiceSession == null && (stack.mResumedActivity == null
                || stack.mResumedActivity.info.applicationInfo.uid != callingUid)) {
            // 检查调用进程是否有权限切换Application
            if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
                    realCallingPid, realCallingUid, "Activity start")) {
                // 如果调用进程没有权限切换Activity,则只能把这次Activity启动请求保存起来,
                // 后续有机会再启动它
                PendingActivityLaunch pal =
                        new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
                // 所有Pending的请求均保存到AMS mPendingActivityLaunches变量中
                mPendingActivityLaunches.add(pal);
                ActivityOptions.abort(options);
                return ActivityManager.START_SWITCHES_CANCELED;
            }
        }
        if (mService.mDidAppSwitch) { // 用于控制app switch
            // This is the second allowed switch since we stopped switches,
            // so now just generally allow switches. Use case: user presses
            // home (switches disabled, switch to home, mDidAppSwitch now true);
            // user taps a home icon (coming from home so allowed, we hit here
            // and now allow anyone to switch again).
            mService.mAppSwitchesAllowedTime = 0;
        } else {
            mService.mDidAppSwitch = true;
        }
        doPendingActivityLaunchesLocked(false);
        // 调用startActivityUncheckedLocked函数
        err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
                startFlags, true, options, inTask);
        if (err < 0) {
            // If someone asked to have the keyguard dismissed on the next
            // activity start, but we are not actually doing an activity
            // switch... just dismiss the keyguard now, because we
            // probably want to see whatever is behind it.
            notifyActivityDrawnForKeyguard();
        }
        return err;
    }

二)、先来看看app switch,它虽然是一个小变量,但是意义重大,关于resume/stopAppSwitches的介绍
AMS提供了两个函数,用于暂时,禁止App切换,为什么会有这种需求? 因为当某些重要(例如设置账号)
Activity处于前台(即用户当前所见的Activity)时,不希望系统因用户操作之外的原因而切换Activity(例如来电)。

    @Override
    public void stopAppSwitches() {
        // 检查调用进程是否有STOP_APP_SWITCHES权限
        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
                != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Requires permission "
                    + android.Manifest.permission.STOP_APP_SWITCHES);
        }
        synchronized (this) {
            // 设置一个超时时间,过了这个时间,AMS可以重新切换App(switch app)
            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
                    + APP_SWITCH_DELAY_TIME;
            mDidAppSwitch = false; // 设置mDidAppSwitch为false
            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
            // 防止应用进程调用了stop却没有调用resume,5秒后处理该消息
            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
        }
    }

以上代码中有两点需要注意:
1、此处控制机制名为app switch, 而不是activity switch。为什么? 因为从受保护的
Activity中启动另一个Activity,那么这个新Activity的目的应该是针对同一任务,
这次启动就不应该受app switch的制约了,反而应该对其打开绿灯。目前,
在执行Settings中设置设备策略(DevicePlicy)时就会stopAppSwitch。
2、执行stopAppSwitch后,应用程序应该调用resumeAppSwitches以允许app switch,
但是为了防止应用程序有意或无意忘记resume app switch,系统设置了一个超时时间(5s)
过了这个时间,系统将处理相应的消息,内部会resume app switch
三)、再看resumeAppSwitch函数

    public void resumeAppSwitches() {
        // 检测调用进程是否具有STOP_APP_SWITCHES权限
        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
                != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Requires permission "
                    + android.Manifest.permission.STOP_APP_SWITCHES);
        }
        synchronized (this) {
            // Note that we don't execute any pending app switches... we will
            // let those wait until either the timeout, or the next start
            // activity request.
            mAppSwitchesAllowedTime = 0;
        }
    }

在resumeAppSwitches中只设置mAppSwitchesAllowTime的值为0,它并不处理在stop和resume这段时间内积攒起来的Pending请求,
那么这些请求时在何时被处理的?
1、从前面代码可知,如果在执行resume app switch后,又有新的请求需要处理,则先处理那些pending的请求
(调用doPendingActivityLaunchesLocked)。
2、在resumeAppSwitches中并未撤销stopAppSwitches函数中设置的超时消息,所以在处理那条超时消息,
所以在处理那条消息的过程中,也会处理pending的请求。
注: 在本例中,由于不考虑app switch的情况,那么接下来的工作就是调用startActivityUncheckLocked函数
来处理本次Activity的启动请求。此时,我们已经创建了一个ActivityRecord用于保存目标Acticity的相关信息

Step 9. ActivityStackSupervisor.startActivityUncheckedLocked

ActivityStackSupervisor.java (frameworks\base\services\core\java\com\android\server\am)

四)、startActivityUncheckLocked函数分析
startActivityUncheckLocked函数比较长,但目的比较简单,为新创建的ActivityRecord找到一个合适的Task。
本例最终结果就是创建一个新的Task,其中startActivityUncheckLocked函数比较复杂,分为三段进行分析

1、确定是否需要为新的Activity创建一个Task,即是否设置FLAG_ACTIVITY_NEW_TASK标志
2、找到一个合适的Task然后做一些处理
3、创建一个新的TaskRecord,并调用startAcitivityLocked函数进行处理
4、首先调用adjustStackFocus()判断目标Activity是否是普通APP还是Home,对应的Stack是否已经创建,若未创建,则创建对应Stack。然后根据启动的Flag和启动模式,判断是否需要在新的Task里运行目标Activity。若需要新的Task,则new 一个TaskRecord,若不需要,则获得当前Taskd的对象,并将TaskRecord和对应的ActivityRecord 关联起来。

  final int startActivityUncheckedLocked(......) {
        //
        final Intent intent = r.intent;
        final int callingUid = r.launchedFromUid;
        // 函数首先获得intent的标志值,保存在launchFlags变量中。
        int launchFlags = intent.getFlags();
        // 判断是否需要调用本次Acivity启动而被系统移到后台的当前Activity的
        // onUserLeaveHint 函数,
        mUserLeaving = (launchFlags & Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
        // If the caller has asked not to resume at this point, we make note
        // of this in the record so that we can skip it when trying to find
        // the top running activity.
        if (!doResume) {
            r.delayedResume = true;
        }
        // 本例的notTop为空
        ActivityRecord notTop =
                (launchFlags & Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
        //
        if (sourceRecord == null && inTask != null && inTask.stack != null) {
            final Intent baseIntent = inTask.getBaseIntent();
            final ActivityRecord root = inTask.getRootActivity();
            if (baseIntent == null) {
                ActivityOptions.abort(options);
                throw new IllegalArgumentException("Launching into task without base intent: "
                        + inTask);
            }
            // If this task is empty, then we are adding the first activity -- it
            // determines the root, and must be launching as a NEW_TASK.
            if (launchSingleInstance || launchSingleTask) {
                if (!baseIntent.getComponent().equals(r.intent.getComponent())) {
                    ActivityOptions.abort(options);
                    throw new IllegalArgumentException("Trying to launch singleInstance/Task "
                            + r + " into different task " + inTask);
                }
                if (root != null) {
                    ActivityOptions.abort(options);
                    throw new IllegalArgumentException("Caller with inTask " + inTask
                            + " has root " + root + " but target is singleInstance/Task");
                }
            }
            // If task is empty, then adopt the interesting intent launch flags in to the
            // activity being started.
            if (root == null) {
                final int flagsOfInterest = Intent.FLAG_ACTIVITY_NEW_TASK
                        | Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NEW_DOCUMENT
                        | Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
                launchFlags = (launchFlags & ~flagsOfInterest)
                        | (baseIntent.getFlags() & flagsOfInterest);
                intent.setFlags(launchFlags);
                inTask.setIntent(r);
                addingToTask = true;
            } else if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
                addingToTask = false;
            } else {
                addingToTask = true;
            }
            reuseTask = inTask;
        } else {
            inTask = null;
        }
        if (inTask == null) {
            if (sourceRecord == null) {
                // 如果请求的发起者为空,则需要新建一个Task
                if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0 && inTask == null) {
                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
                }
                // 如果sourceRecord单独占一个Instance,则新的Activity必然处于另一个Task中
            } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
                // 如果启动模式设置为singleTask或singleInstance,则也要创建Task
                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
            } else if (launchSingleInstance || launchSingleTask) {
                // The activity being started is a single instance... it always
                // gets launched into its own task.
                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
            }
        }
        ActivityInfo newTaskInfo = null;
        Intent newTaskIntent = null;
        ActivityStack sourceStack;
        if (sourceRecord != null) {
            if (sourceRecord.finishing) {
                //
                if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
                    newTaskInfo = sourceRecord.info;
                    newTaskIntent = sourceRecord.task.intent;
                }
                sourceRecord = null;
                sourceStack = null;
            } else {
                sourceStack = sourceRecord.task.stack;
            }
        } else {
            sourceStack = null;
        }
        boolean movedHome = false;
        ActivityStack targetStack;
        intent.setFlags(launchFlags);
        final boolean noAnimation = (launchFlags & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0;
        // 这么多复杂的逻辑处理,无非就是要找到一个合适的Task,然后对应做一些处理。
        //
        if (((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
                (launchFlags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
                || launchSingleInstance || launchSingleTask) {
        }
        // 第三阶段:
        if (r.packageName != null) {
            // 判断目标Activity是否已经在栈顶,如果是,需要判断是创建一个新的Activity还是调用
            // onNewIntent(singleTop模式的处理)
            ActivityStack topStack = mFocusedStack;
            ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
        // 在本例中,需要创建一个Task
        boolean newTask = false;
        boolean keepCurTransition = false;
        TaskRecord taskToAffiliate = launchTaskBehind && sourceRecord != null ?
                sourceRecord.task : null;
        // Should this be considered a new task?
        if (r.resultTo == null && inTask == null && !addingToTask
                && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
            if (reuseTask == null) {
                // 为该ActivityRecord设置一个新的TaskRecord
                r.setTask(targetStack.createTaskRecord(getNextTaskId(),
                        newTaskInfo != null ? newTaskInfo : r.info,
                        newTaskIntent != null ? newTaskIntent : intent,
                        voiceSession, voiceInteractor, !launchTaskBehind /* toTop */),
                        taskToAffiliate);
            } else {
                r.setTask(reuseTask, taskToAffiliate);
            }
            if (isLockTaskModeViolation(r.task)) {
                Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
            }
            if (!movedHome) {
                if ((launchFlags &
                        (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
                        == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
                    // Caller wants to appear on home activity, so before starting
                    // their own activity we will bring home to the front.
                    r.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
                }
            }
        } else if (sourceRecord != null) {
            final TaskRecord sourceTask = sourceRecord.task;
            if (isLockTaskModeViolation(sourceTask)) {
                Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
            }
            targetStack = sourceTask.stack;
            targetStack.moveToFront("sourceStackToFront");
            final TaskRecord topTask = targetStack.topTask();
            if (topTask != sourceTask) {
                targetStack.moveTaskToFrontLocked(sourceTask, noAnimation, options,
                        r.appTimeTracker, "sourceTaskToFront");
            }
            if (!addingToTask && (launchFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
                // In this case, we are adding the activity to an existing
                // task, but the caller has asked to clear that task if the
                // activity is already running.
                ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
                keepCurTransition = true;
                if (top != null) {
                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
                    top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
                    // For paranoia, make sure we have correctly
                    // resumed the top activity.
                    targetStack.mLastPausedActivity = null;
                    if (doResume) {
                        targetStack.resumeTopActivityLocked(null);
                    }
                    ActivityOptions.abort(options);
                    return ActivityManager.START_DELIVERED_TO_TOP;
                }
            } else if (!addingToTask &&
                    (launchFlags & Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
                // In this case, we are launching an activity in our own task
                // that may already be running somewhere in the history, and
                // we want to shuffle it to the front of the stack if so.
                final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
                if (top != null) {
                    final TaskRecord task = top.task;
                    task.moveActivityToFrontLocked(top);
                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
                    top.updateOptionsLocked(options);
                    top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
                    targetStack.mLastPausedActivity = null;
                    if (doResume) {
                        targetStack.resumeTopActivityLocked(null);
                    }
                    return ActivityManager.START_DELIVERED_TO_TOP;
                }
            }
            // An existing activity is starting this new activity, so we want
            // to keep the new one in the same task as the one that is starting
            // it.
            r.setTask(sourceTask, null);
        } else if (inTask != null) {
            // The caller is asking that the new activity be started in an explicit
            // task it has provided to us.
            if (isLockTaskModeViolation(inTask)) {
                Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
            }
            targetStack = inTask.stack;
            targetStack.moveTaskToFrontLocked(inTask, noAnimation, options, r.appTimeTracker,
                    "inTaskToFront");
            // Check whether we should actually launch the new activity in to the task,
            // or just reuse the current activity on top.
            ActivityRecord top = inTask.getTopActivity();
            if (top != null && top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
                if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
                        || launchSingleTop || launchSingleTask) {
                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top, top.task);
                    if ((startFlags & ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
                        // We don't need to start a new activity, and
                        // the client said not to do anything if that
                        // is the case, so this is it!
                        return ActivityManager.START_RETURN_INTENT_TO_CALLER;
                    }
                    top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
                    return ActivityManager.START_DELIVERED_TO_TOP;
                }
            }
            if (!addingToTask) {
                // We don't actually want to have this activity added to the task, so just
                // stop here but still tell the caller that we consumed the intent.
                ActivityOptions.abort(options);
                return ActivityManager.START_TASK_TO_FRONT;
            }
            r.setTask(inTask, null);
        } else {
            // This not being started from an existing activity, and not part
            // of a new task... just put it in the top task, though these days
            // this case should never happen.
            targetStack = computeStackFocus(r, newTask);
            targetStack.moveToFront("addingToTopTask");
            ActivityRecord prev = targetStack.topActivity();
            r.setTask(prev != null ? prev.task : targetStack.createTaskRecord(getNextTaskId(),
                    r.info, intent, null, null, true), null);
            mWindowManager.moveTaskToTop(r.task.taskId);
        }
        mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
                intent, r.getUriPermissionsLocked(), r.userId);
        if (sourceRecord != null && sourceRecord.isRecentsActivity()) {
            r.task.setTaskToReturnTo(RECENTS_ACTIVITY_TYPE);
        }
        if (newTask) {
            EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
        }
        ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
        targetStack.mLastPausedActivity = null;
        // 调用startActivityLocked,此时ActivityRecord和TaskRecord均创建完毕
        targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
        if (!launchTaskBehind) {
            // Don't set focus on an activity that's going to the back.
            mService.setFocusedActivityLocked(r, "startedActivity");
        }
        return ActivityManager.START_SUCCESS;
    }

五)、以上代码第三阶段将创建一个新的TaskRecord,并调用startActivityLocked函数

   final void startActivityLocked(ActivityRecord r, boolean newTask,
                                   boolean doResume, boolean keepCurTransition, Bundle options) {
        TaskRecord rTask = r.task;
        final int taskId = rTask.taskId;
        // mLaunchTaskBehind tasks get placed at the back of the task stack.
        if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) {
            // 
            insertTaskAtTop(rTask, r);
            mWindowManager.moveTaskToTop(taskId);
        }
        TaskRecord task = null;
        if (!newTask) { // 如果不是新的Task,则从mHistory中找到对应的AcitivityRecord的位置
        ......
        }
        // 设置ActivityRecord的inHistory变量为true,表示已经加到mHistory数组中了
        task = r.task;
        task.addActivityToTop(r);
        task.setFrontOfTask();
        r.putInHistory();
        // 最终调用resumeTopActivitiesLocked函数,后面我们重点分析这个函数
        if (doResume) {
            mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
        }
    }

Step 10. ActivityStack.resumeTopActivityLocked

ActivityStack.java (frameworks\base\services\core\java\com\android\server\am)
六)、resumeTopActivitiesLocked函数分析
该函数首先判断栈顶是否有需要显示的Activity,没有则启动Launcher,如果有需要显示的,还需要判断是否有需要暂停的Activity,有则执行Activity暂停操作。

    final boolean resumeTopActivityLocked(ActivityRecord prev) {
        return resumeTopActivityLocked(prev, null);
    }
   final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
        if (mStackSupervisor.inResumeTopActivity) {
            /// M: BMW. Add log @{
            if (MultiWindowProxy.isSupported()) {
                if (DEBUG_STACK) Slog.w(TAG, "[BMW] resumeTopActivityLocked:"
                        + "Don't even start recursing Stack:" + this);
            }
            /// @}
            // 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();
            }
            result = resumeTopActivityInnerLocked(prev, options);
        } finally {
            mStackSupervisor.inResumeTopActivity = false;
        }
        return result;
    }

它首先看要启动的Activity是否就是当前处理Resumed状态的Activity,如果是的话,那就什么都不用做,直接返回就可以了;否则再看一 下系统当前是否休眠状态,如果是的话,再看看要启动的Activity是否就是当前处于堆栈顶端的Activity,如果是的话,也是什么都不用做。
上面两个条件都不满足,因此,在继续往下执行之前,首先要把当处于Resumed状态的Activity推入Paused状态,然后才可以启动新的 Activity。但是在将当前这个Resumed状态的Activity推入Paused状态之前,首先要看一下当前是否有Activity正在进入 Pausing状态,如果有的话,当前这个Resumed状态的Activity就要稍后才能进入Paused状态了,这样就保证了所有需要进入 Paused状态的Activity串行处理。
这里没有处于Pausing状态的Activity,即mPausingActivity为null,而且mResumedActivity也不为 null,于是就调用startPausingLocked函数把Launcher推入Paused状态去了。

  private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
        /* 1、从mHistory中找到第一个需要启动的ActivityRecord 2、函数先通过调用topRunningActivityLocked函数获得堆栈顶端的Activity, 这里就是MainActivity了,这是在上面的Step 9设置好的,保存在next变量中。 */
        final ActivityRecord next = topRunningActivityLocked(null);
        /* 接下来把mUserLeaving的保存在本地变量userLeaving中,然后重新设置为false, 在上面的Step 9中,mUserLeaving的值为true,因此,这里的userLeaving为true。 */
        final boolean userLeaving = mStackSupervisor.mUserLeaving;
        mStackSupervisor.mUserLeaving = false;
        final TaskRecord prevTask = prev != null ? prev.task : null;
        if (next == null) {
            // There are no more activities!
            final String reason = "noMoreActivities";
            if (!mFullscreen) {
                // Try to move focus to the next visible stack with a running activity if this
                // stack is not covering the entire screen.
                final ActivityStack stack = getNextVisibleStackLocked();
                if (adjustFocusToNextVisibleStackLocked(stack, reason)) {
                    return mStackSupervisor.resumeTopActivitiesLocked(stack, prev, null);
                }
            }
            // Let's just start up the Launcher...
            ActivityOptions.abort(options);
            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
            // Only resume home if on home display
            final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ?
                    HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();
            return isOnHomeDisplay() &&
                    mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, reason);
        }
        // 本例中,next将是目标Activity
        next.delayedResume = false;
        // If the top activity is the resumed one, nothing to do.
        if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
                mStackSupervisor.allResumedActivitiesComplete()) {
            // Make sure we have executed any pending transitions, since there
            // should be nothing left to do at this point.
            mWindowManager.executeAppTransition();
            mNoAnimActivities.clear();
            ActivityOptions.abort(options);
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                    "resumeTopActivityLocked: Top activity resumed " + next);
            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
            return false;
        }
        final TaskRecord nextTask = next.task;
        if (prevTask != null && prevTask.stack == this &&
                prevTask.isOverHomeStack() && prev.finishing && prev.frontOfTask) {
            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
            if (prevTask == nextTask) {
                prevTask.setFrontOfTask();
            } else if (prevTask != topTask()) {
                // This task is going away but it was supposed to return to the home stack.
                // Now the task above it has to return to the home task instead.
                final int taskNdx = mTaskHistory.indexOf(prevTask) + 1;
                mTaskHistory.get(taskNdx).setTaskToReturnTo(HOME_ACTIVITY_TYPE);
            } else if (!isOnHomeDisplay()) {
                return false;
            } else if (!isHomeStack()) {
                if (DEBUG_STATES) Slog.d(TAG_STATES,
                        "resumeTopActivityLocked: Launching home next");
                final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ?
                        HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();
                return isOnHomeDisplay() &&
                        mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, "prevFinished");
            }
        }
        /* 当我们处理休眠状态时,mLastPausedActivity保存堆栈顶端的Activity,因为当前不是休眠状态,所以mLastPausedActivity为null。 */
        if (mService.isSleepingOrShuttingDown()
                && mLastPausedActivity == next
                && mStackSupervisor.allPausedActivitiesComplete()) {
            // Make sure we have executed any pending transitions, since there
            // should be nothing left to do at this point.
            mWindowManager.executeAppTransition();
            mNoAnimActivities.clear();
            ActivityOptions.abort(options);
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                    "resumeTopActivityLocked: Going to sleep and all paused");
            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
            return false;
        }
        // Make sure that the user who owns this activity is started. If not,
        // we will just leave it as is because someone should be bringing
        // another user's activities to the top of the stack.
        if (mService.mStartedUsers.get(next.userId) == null) {
            Slog.w(TAG, "Skipping resume of top activity " + next
                    + ": user " + next.userId + " is stopped");
            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
            return false;
        }
        //将该ActivityRecord从下面几个队列中移除
        mStackSupervisor.mStoppingActivities.remove(next);
        mStackSupervisor.mGoingToSleepActivities.remove(next);
        next.sleeping = false;
        mStackSupervisor.mWaitingVisibleActivities.remove(next);
        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resuming " + next);
        // If we are currently pausing an activity, then don't do anything
        // until that is done.
        if (!mStackSupervisor.allPausedActivitiesComplete()) {
            if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
                    "resumeTopActivityLocked: Skip resume: some activity pausing.");
            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
            return false;
        }
        // Okay we are now going to start a switch, to 'next'. We may first
        // have to pause the current activity, but this is an important point
        // where we have decided to go to 'next' so keep track of that.
        // XXX "App Redirected" dialog is getting too many false positives
        // at this point, so turn off for now.
        if (false) {
            if (mLastStartedActivity != null && !mLastStartedActivity.finishing) {
                long now = SystemClock.uptimeMillis();
                final boolean inTime = mLastStartedActivity.startTime != 0
                        && (mLastStartedActivity.startTime + START_WARN_TIME) >= now;
                final int lastUid = mLastStartedActivity.info.applicationInfo.uid;
                final int nextUid = next.info.applicationInfo.uid;
                if (inTime && lastUid != nextUid
                        && lastUid != next.launchedFromUid
                        && mService.checkPermission(
                        android.Manifest.permission.STOP_APP_SWITCHES,
                        -1, next.launchedFromUid)
                        != PackageManager.PERMISSION_GRANTED) {
                    mService.showLaunchWarningLocked(mLastStartedActivity, next);
                } else {
                    next.startTime = now;
                    mLastStartedActivity = next;
                }
            } else {
                next.startTime = SystemClock.uptimeMillis();
                mLastStartedActivity = next;
            }
        }
        mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid);
        // We need to start pausing the current activity so the top one
        // can be resumed...
        boolean dontWaitForPause = (next.info.flags & ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0;
        boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);
        /* 1、如果当前正在中断一个Acitivity,需先等待那个Activity pause完毕,然后系统会重新 调用resumeTopActivityLocked函数以找到下一个个启动的Activity 2、mResumedActivity 指向上一次启动的Acitivity,也就是当前界面显示的这个Acitivity 在本例中,当前Activity就是Home界面 3、如果mResumedActivity为空,则一定是系统第一个启动的Acitivity,读者应该能猜出来他就是home */
        if (mResumedActivity != null) {
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                    "resumeTopActivityLocked: Pausing " + mResumedActivity);
            // 先中断Home,这种情况放在最后进行分析
            pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
        }
        if (pausing) {
            // At this point we want to put the upcoming activity's process
            // at the top of the LRU list, since we know we will be needing it
            // very soon and it would be a waste to let it get killed if it
            // happens to be sitting towards the end.
            if (next.app != null && next.app.thread != null) {
                mService.updateLruProcessLocked(next.app, true, null);
            }
            return true;
        }
        // If the most recent activity was noHistory but was only stopped rather
        // than stopped+finished because the device went to sleep, we need to make
        // sure to finish it as we're making a new activity topmost.
        if (mService.isSleeping() && mLastNoHistoryActivity != null &&
                !mLastNoHistoryActivity.finishing) {
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                    "no-history finish of " + mLastNoHistoryActivity + " on new resume");
            requestFinishActivityLocked(mLastNoHistoryActivity.appToken, Activity.RESULT_CANCELED,
                    null, "resume-no-history", false);
            mLastNoHistoryActivity = null;
        }
        // 如果prev不为空,则需要通知WMS进行与Activity切换相关的工作
        if (prev != null && prev != next) {
        }
        // 通知PKMS修改该package stop 状态
        try {
            AppGlobals.getPackageManager().setPackageStoppedState(
                    next.packageName, false, next.userId); /* TODO: Verify if correct userid */
        } catch (RemoteException e1) {
        }
        // We are starting up the next activity, so tell the window manager
        // that the previous one will be hidden soon. This way it can know
        // to ignore it when computing the desired screen orientation.
        if (prev != null) {
            // 还是和wms有关,通知停止绘画
        }
        // 如果该ActivityRecord已有对应的进程存在,则需要重启Activity,就本例而言,
        // 此进程还不存在,所以要先创建一个应用进程
        if (next.app != null && next.app.thread != null && needResume) {
        } else {
            //第一次启动
            if (!next.hasBeenLaunched) {
                next.hasBeenLaunched = true;
            } else {
                // 通知wms显示启动界面
            }
            // 调用另外一个startSpecificActivityLocked函数
            mStackSupervisor.startSpecificActivityLocked(next, true, true);
        }
        return true;
    }

Step 11. ActivityStack.startPausingLocked

一、
1、当启动一个新Activity时,系统将先行处理当前的Activity,即调用startPausingLocked函数暂停当前Acitivity

    final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming,
                                     boolean dontWait) {
        if (mPausingActivity != null) {
            if (!mService.isSleeping()) {
                // Avoid recursion among check for sleep and complete pause during sleeping.
                // Because activity will be paused immediately after resume, just let pause
                // be completed by the order of activity paused from clients.
                completePauseLocked(false);
            }
        }
        // mResumedActivity 保存当前正现实的Activity
函数首先把mResumedActivity保存在本地变量prev中。在上一步Step 10中,说到mResumedActivity就是Launcher,因此,这里把Launcher进程中的ApplicationThread对象取出来,通过它来通知Launcher这个Activity它要进入Paused状态了。当然,这里的prev.app.thread是一个ApplicationThread对象的远程接口,通过调用这个远程接口的schedulePauseActivity来通知Launcher进入Paused状态。
        ActivityRecord prev = mResumedActivity;
        if (prev == null) {
            if (!resuming) {
                mStackSupervisor.resumeTopActivitiesLocked();
            }
            return false;
        }
        if (mActivityContainer.mParentActivity == null) {
            // Top level stack, not a child. Look for child stacks.
            mStackSupervisor.pauseChildStacks(prev, userLeaving, uiSleeping, resuming, dontWait);
        }
        // 设置mPausingActivity为当前Activity
        mResumedActivity = null;
        mPausingActivity = prev;
        mLastPausedActivity = prev;
        mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
                || (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null;
        prev.state = ActivityState.PAUSING; // 设置状态为PAUSING
        prev.task.touchActiveTime();
        clearLaunchTime(prev);
        final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();
        if (mService.mHasRecents && (next == null || next.noDisplay || next.task != prev.task || uiSleeping)) {
            /// M: Add for launch time enhancement @{
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER | Trace.TRACE_TAG_PERF, "amScreenCapture");
            if (!prev.isHomeActivity()) {
                prev.updateThumbnailLocked(screenshotActivities(prev), null);
            }
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER | Trace.TRACE_TAG_PERF);
            /// @}
        }
        stopFullyDrawnTraceIfNeeded();
        mService.updateCpuStats();
        if (prev.app != null && prev.app.thread != null) {
            try {
                EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
                        prev.userId, System.identityHashCode(prev),
                        prev.shortComponentName);
                mService.updateUsageStats(prev, false);
                // 调用当前Activity所在进程的schedulePauseActivity函数
参数prev.finishing表示prev所代表的Activity是否正在等待结束的Activity列表中,由于Laucher这个Activity还没结束,所以这里为false;参数prev.configChangeFlags表示哪些config发生了变化,这里我们不关心它的值。
                prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
                        userLeaving, prev.configChangeFlags, dontWait);
            } catch (Exception e) { }
            // 获取WakeLock,以防止在Activity切换过程中掉电
        if (!uiSleeping && !mService.isSleepingOrShuttingDown()) {
            mStackSupervisor.acquireLaunchWakelock();
        }
        if (mPausingActivity != null) {
            // 暂停输入事件派发
            if (!uiSleeping) {
                prev.pauseKeyDispatchingLocked();
            } else if (DEBUG_PAUSE) {
                Slog.v(TAG_PAUSE, "Key dispatch not paused for screen off");
            }
            if (dontWait) {
                // If the caller said they don't want to wait for the pause, then complete
                // the pause now.
                completePauseLocked(false);
                return false;
            } else {
                // 设置PAUSE超时,时间为500ms
                Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
                msg.obj = prev;
                prev.pauseTime = SystemClock.uptimeMillis();
                mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);
                return true;
            }
        } else {
            if (!resuming) {
                mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null);
            }
            return false;
        }
    }

startPausingLocked将调用应用程序进程的schedulePauseActivity函数,并设置500ms的超时时间,所以应用进程需要尽快完成相关操作,和scheduleLaunchActivity一样,
schedulePauseActivity将向ActivityThread主线程发送PAUSE_ACTIVITY消息,最终该消息由handlePauseAcitivity来处理

Step 12. ApplicationThreadProxy.schedulePauseActivity

ApplicationThreadNative.java (frameworks\base\core\java\android\app)

   public final void schedulePauseActivity(IBinder token, boolean finished,
            boolean userLeaving, int configChanges, boolean dontReport) throws RemoteException {
        Parcel data = Parcel.obtain();
        data.writeInterfaceToken(IApplicationThread.descriptor);
        data.writeStrongBinder(token);
        data.writeInt(finished ? 1 : 0);
        data.writeInt(userLeaving ? 1 :0);
        data.writeInt(configChanges);
        data.writeInt(dontReport ? 1 : 0);
        mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null,
                IBinder.FLAG_ONEWAY);
        data.recycle();
    }

这个函数通过Binder进程间通信机制进入到ApplicationThread.schedulePauseActivity函数中。

Step 13. ApplicationThread.schedulePauseActivity

        public final void schedulePauseActivity(IBinder token, boolean finished,
                boolean userLeaving, int configChanges, boolean dontReport) {
            sendMessage(
                    finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
                    token,
                    (userLeaving ? 1 : 0) | (dontReport ? 2 : 0),
                    configChanges);
        }

这里调用的函数SendMessage是ActivityThread类的成员函数。
上面说到,这里的finished值为false,因此,SendMessage的第一个参数值为H.PAUSE_ACTIVITY,表示要暂停token所代表的Activity,即Launcher。

Step 14. ActivityThread.SendMessage

ActivityThread.java (frameworks\base\core\java\android\app)

    private void sendMessage(int what, Object obj, int arg1, int arg2) {
        sendMessage(what, obj, arg1, arg2, false);
    }
    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);
    }

这里首先将相关信息组装成一个msg,然后通过mH成员变量发送出去,mH的类型是H,继承于Handler类,是ActivityThread的内部类,因此,这个消息最后由H.handleMessage来处理。

Step 15. H.handleMessage

    public void handleMessage(Message msg) {
        switch (msg.what) {
            case PAUSE_ACTIVITY:
                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
                handlePauseActivity((IBinder)msg.obj, false, (msg.arg1&1) != 0, msg.arg2,
                        (msg.arg1&2) != 0);
                maybeSnapshot();
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                break;
        }
    }

这里调用ActivityThread.handlePauseActivity进一步操作,msg.obj是一个ActivityRecord对象的引用,它代表的是Launcher这个Activity。

Step 16. ActivityThread.handlePauseActivity

2、ActivityThread.java (frameworks\base\core\java\android\app)

   private void handlePauseActivity(IBinder token, boolean finished,
                                     boolean userLeaving, int configChanges, boolean dontReport) {
        // 当Activity处于finishing状态时,finiished参数为true,不过在本例中该值为false
        ActivityClientRecord r = mActivities.get(token);
        if (r != null) {
            //调用Activity的onUserLeaving函数
            if (userLeaving) {
                performUserLeavingActivity(r);
            }
            r.activity.mConfigChangeFlags |= configChanges;
            // 调用Activity的onPause函数
            performPauseActivity(token, finished, r.isPreHoneycomb());
            // Make sure any pending writes are now committed.
            if (r.isPreHoneycomb()) {
                QueuedWork.waitToFinish();
            }
            // Tell the activity manager we have paused.
            if (!dontReport) {
                try {
                    // 调用AMS的activityPaused函数
                    ActivityManagerNative.getDefault().activityPaused(token);
                } catch (RemoteException ex) {
                }
            }
            mSomeActivitiesChanged = true;
        }
    }

函数首先将Binder引用token转换成ActivityRecord的远程接口ActivityClientRecord,然后做了三个事情:1. 如果userLeaving为true,则通过调用performUserLeavingActivity函数来调用Activity.onUserLeaveHint通知Activity,用户要离开它了;2. 调用performPauseActivity函数来调用Activity.onPause函数,我们知道,在Activity的生命周期中,当它要让位于其它的Activity时,系统就会调用它的onPause函数;3. 它通知ActivityManagerService,这个Activity已经进入Paused状态了,ActivityManagerService现在可以完成未竟的事情,即启动MainActivity了。

Step 17. ActivityManagerProxy.activityPaused

ActivityManagerNative.java (frameworks\base\core\java\android\app)

    public void activityPaused(IBinder token) throws RemoteException
    {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeStrongBinder(token);
        mRemote.transact(ACTIVITY_PAUSED_TRANSACTION, data, reply, 0);
        reply.readException();
        data.recycle();
        reply.recycle();
    }

这里通过Binder进程间通信机制就进入到ActivityManagerService.activityPaused函数中去了。

Step 18. ActivityManagerService.activityPaused

ActivityManagerService.java (frameworks\base\services\core\java\com\android\server\am)

    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);
    }

这里,又再次进入到ActivityStack类中,执行activityPaused函数。

Step 19. ActivityStack.activityPausedLocked

ActivityStack.java (frameworks\base\services\core\java\com\android\server\am)

    final void activityPausedLocked(IBinder token, boolean timeout) {
        final ActivityRecord r = isInStackLocked(token);
        if (r != null) {
            // 从消息队列中撤销PAUSE_TIMEOUT_MSG消息
            mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
            if (mPausingActivity == r) {
                // 完成本次pause操作
                completePauseLocked(true);
            } else {
                // 设置ActivityRecotd状态
                if (r.finishing && r.state == ActivityState.PAUSING) {
                    finishCurrentActivityLocked(r, FINISH_AFTER_VISIBLE, false);
                }
            }
            /// M: activity state notifier @{
            mService.notifyActivityState(r.packageName, r.getFocusAppPid(),
                    r.realActivity.getShortClassName(),
                    IActivityStateNotifier.ActivityState.Paused);
            /// @}
        }
    }

这里通过参数token在mHistory列表中得到ActivityRecord,从上面我们知道,这个ActivityRecord代表的是 Launcher这个Activity,而我们在Step 11中,把Launcher这个Activity的信息保存在mPausingActivity中,因此,这里mPausingActivity等于r, 于是,执行completePauseLocked操作。

Step 20. ActivityStack.completePauseLocked

3、ActivityStack.java (frameworks\base\services\core\java\com\android\server\am)
最后通过resumeTopActivitiesLocked来启动目标Acitivity

    private void completePauseLocked(boolean resumeNext) {
        ActivityRecord prev = mPausingActivity;
        if (prev != null) {
            prev.state = ActivityState.PAUSED;
            if (prev.finishing) {
                prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false);
            } else if (prev.app != null) {
                if (prev.configDestroy) {
                    destroyActivityLocked(prev, true, "pause-config");
                } else if (!hasVisibleBehindActivity() || mService.isSleepingOrShuttingDown()) {
                    // 将刚才被暂停的Activity保存到mStoppingActivities中
                    mStackSupervisor.mStoppingActivities.add(prev);
                    if (mStackSupervisor.mStoppingActivities.size() > 3 ||
                            prev.frontOfTask && mTaskHistory.size() <= 1) {
                        // 如果被暂停的Activity超过3个,则发送IDLE_NOW_MSG消息,该消息最终由我们前面介绍的activityIdleInternal处理
                        mStackSupervisor.scheduleIdleLocked();
                    } else {
                        mStackSupervisor.checkReadyForSleepLocked();
                    }
                }
            } else { // 设置mPausingActivity为null
                prev = null;
            }
            // It is possible the activity was freezing the screen before it was paused.
            // In that case go ahead and remove the freeze this activity has on the screen
            // since it is no longer visible.
            prev.stopFreezingScreenLocked(true /*force*/);
            mPausingActivity = null;
        }
        if (resumeNext) {
            final ActivityStack topStack = mStackSupervisor.getFocusedStack();
            if (!mService.isSleepingOrShuttingDown()) { // resumeTopActivitiesLocked将启动目标activity
                mStackSupervisor.resumeTopActivitiesLocked(topStack, prev, null);
            } else {
            }
        }
    }

函数首先把mPausingActivity变量清空,因为现在不需要它了,然后调用resumeTopActivityLokced进一步操作,它传入的参数即为代表Launcher这个Activity的ActivityRecord。

Step 21. ActivityStack.resumeTopActivityLokced

通过上面的Step 9,我们知道,当前在堆栈顶端的Activity为我们即将要启动的MainActivity,这里通过调用topRunningActivityLocked将它取回来,保存在next变量中。之前最后一个Resumed状态的Activity,即Launcher,到了这里已经处于Paused状态了,因此,mResumedActivity为null。最后一个处于Paused状态的Activity为Launcher,因此,这里的mLastPausedActivity就为Launcher。前面我们为MainActivity创建了ActivityRecord后,它的app域一直保持为null。有了这些信息后,上面这段代码就容易理解了,它最终调用startSpecificActivityLocked进行下一步操作。

Step 22. ActivityStackSupervisor.startSpecificActivityLocked

ActivityStackSupervisor.java (\frameworks\base\services\core\java\com\android\server\am)

 void startSpecificActivityLocked(ActivityRecord r,
                                     boolean andResume, boolean checkConfig) {
        // 注意,这里由于是第一次启动应用程序的Activity,所以下面语句:
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);
        r.task.stack.setLaunchTime(r);
        /* 取回来的app为null。在Activity应用程序中的AndroidManifest.xml配置文件中, 我们没有指定Application标签的process属性,系统就会默认使用package的名称, 这里就是"shy.luo.activity"了。每一个应用程序都有自己的uid,因此,这里uid + process的组合就 可以为每一个应用程序创建一个ProcessRecord。当然,我们可以配置两个应用程序具有相同的uid和package, 或者在AndroidManifest.xml配置文件的application标签或者activity标签中显式指定相同的process属性值, 这样,不同的应用程序也可以在同一个进程中启动。 */
        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) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }
        }
        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }

Step 23. ActivityManagerService.startProcessLocked

    final ProcessRecord startProcessLocked(......) {
        long startTime = SystemClock.elapsedRealtime();
        ProcessRecord app;
        if (!isolated) {
            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
            ......
            String hostingNameStr = hostingName != null
                    ? hostingName.flattenToShortString() : null;
            if (app == null) {
                checkTime(startTime, "startProcess: creating new process record");
                app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
                if (app == null) {
                    Slog.w(TAG, "Failed making new process record for "
                            + processName + "/" + info.uid + " isolated=" + isolated);
                    return null;
                }
                app.crashHandler = crashHandler;
                checkTime(startTime, "startProcess: done creating new process record");
            } else {
                // If this is a new package in the process, add the package to the list
                app.addPackage(info.packageName, info.versionCode, mProcessStats);
                checkTime(startTime, "startProcess: added package to existing proc");
            }
            ......
            startProcessLocked(
                    app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
            checkTime(startTime, "startProcess: done starting proc!");
            return (app.pid != 0) ? app : null;
        }
    }

这里再次检查是否已经有以process + uid命名的进程存在,在我们这个情景中,返回值app为null,因此,后面会创建一个ProcessRecord,并存保存在成员变量mProcessNames中,最后,调用另一个startProcessLocked函数进一步操作:

    private final void startProcessLocked(ProcessRecord app, String hostingType,
                                          String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {

            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);
    }

这里主要是调用Process.start接口来创建一个新的进程,新的进程会导入android.app.ActivityThread类,并且执行它的main函数,这就是为什么我们前面说每一个应用程序都有一个ActivityThread实例来对应的原因。

4、根据前面的介绍,此次目标Acitivity将走完onCreate、onStart和onResume流程,但是被暂停的Activity才刚走完onPause流程,那么什么时候调用onStop?
答案就在activityIdelInternal中,他将成为mStopingActivities中的成员调用stopActivityLocked函数

    final void stopActivityLocked(ActivityRecord r) {
        if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
                || (r.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0) {
            if (!r.finishing) {
                if (!mService.isSleeping()) {
                    if (requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
                            "stop-no-history", false)) {
                        // Activity was finished, no need to continue trying to schedule stop.
                        adjustFocusedActivityLocked(r, "stopActivityFinished");
                        r.resumeKeyDispatchingLocked();
                        return;
                    }
                } else {
                }
            }
        }
        if (r.app != null && r.app.thread != null) {
            adjustFocusedActivityLocked(r, "stopActivity");
            r.resumeKeyDispatchingLocked();
            try {
                r.stopped = false;
                // 设置STOPPING状态,并调用对应的scheduleStopActivity函数
                r.state = ActivityState.STOPPING;
                r.app.thread.scheduleStopActivity(r.appToken, r.visible, r.configChangeFlags);
                if (mService.isSleepingOrShuttingDown()) {
                    r.setSleeping(true);
                }
                Message msg = mHandler.obtainMessage(STOP_TIMEOUT_MSG, r);
                mHandler.sendMessageDelayed(msg, STOP_TIMEOUT);
            } catch (Exception e) {
            }
        }
    }

5、对应进程scheduleStopActivity函数将根据visible的情况,向主线程消息循环发送H.STOP_ACTIVITY_HIDE和 H.STOP_ACTIVITY_SHOW 消息。
不论哪种情况,最终都由handleStopActivity来处理。

   private void handleStopActivity(IBinder token, boolean show, int configChanges) {
        ActivityClientRecord r = mActivities.get(token);
        r.activity.mConfigChangeFlags |= configChanges;
        StopInfo info = new StopInfo();
        // 调用Activity的onStop函数
        performStopActivityInner(r, info, show, true);
        updateVisibility(r, show);
        info.activity = r;
        info.state = r.state;
        info.persistentState = r.persistentState;
        mH.post(info);
        mSomeActivitiesChanged = true;
    }

Step 24. ActivityThread.main

一、应用进程创建及初始化
1、ActivityThread.java (frameworks\base\core\java\android\app)

    public static void main(String[] args) {
        logAppLaunchTime(TAG, "ActivityThread is created"); /// M: It's for debugging App Launch time
        SamplingProfilerIntegration.start();
        // 和调试及strictMode有关
        CloseGuard.setEnabled(false);
        Environment.initForCurrentUser();
        AndroidKeyStoreProvider.install();
        // Make sure TrustedCertificateStore looks in the right place for CA certificates
        final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
        TrustedCertificateStore.setDefaultUserDirectory(configDir);
        // 设置进程名为"<pre-initialized>"
        Process.setArgV0("<pre-initialized>");
        // 准备主线程消息循环
        Looper.prepareMainLooper();
        // 创建一个ActivityThread对象
        ActivityThread thread = new ActivityThread();
        // 调用attach函数,注意其参数数值false
        thread.attach(false);
        Looper.loop(); // 进入主线程消息循环
    }

在main函数中内部将创建一个消息循环Loop,接着调用ActivityThread的attach函数,最终将主线程加入消息循环。

2、我们在分析AMS的setSystemProcess是曾分析过ActivityThread的attach函数,那时传入的参数值为true,现在看看设置为false的情况
ActivityThread.java (frameworks\base\core\java\android\app)

    private void attach(boolean system) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
            ViewRootImpl.addFirstDrawHandler(new Runnable() {
                @Override
                public void run() {
                    ensureJitEnabled();
                }
            });
            // 设置在DDMS中看到的本进程的名字为"<pre-initialized>"
            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                    UserHandle.myUserId());
            // 设置RuntimeInit的mApplicationObject参数,后续会介绍RuntimeInit类
            RuntimeInit.setApplicationObject(mAppThread.asBinder());
            // 获取和AMS交互的Binder客户端
            final IActivityManager mgr = ActivityManagerNative.getDefault();
            try {
                // 调用AMS的attachApplication,mAppThread为ApplicationThread类型,它是应用进程和AMS交互的接口
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                // Ignore
            }
            // Watch for getting close to heap limit.
            BinderInternal.addGcWatcher(new Runnable() {
                @Override
                public void run() {
                    if (!mSomeActivitiesChanged) {
                        return;
                    }
                    Runtime runtime = Runtime.getRuntime();
                    long dalvikMax = runtime.maxMemory();
                    long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
                    if (dalvikUsed > ((3 * dalvikMax) / 4)) {
                        if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax / 1024)
                                + " total=" + (runtime.totalMemory() / 1024)
                                + " used=" + (dalvikUsed / 1024));
                        mSomeActivitiesChanged = false;
                        try {
                            mgr.releaseSomeActivities(mAppThread);
                        } catch (RemoteException e) {
                        }
                    }
                }
            });
        } else {// system process处理
        }
    }
这个函数在进程中创建一个ActivityThread实例,然后调用它的attach函数,接着就进入消息循环了,直到最后进程退出。
   函数attach最终调用了ActivityManagerService的远程接口ActivityManagerProxy的attachApplication函数,传入的参数是mAppThread,这是一个ApplicationThread类型的Binder对象,它的作用是用来进行进程间通信的。

Step 25. 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());
        mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
        reply.readException();
        data.recycle();
        reply.recycle();
    }

这里通过Binder驱动程序,最后进入ActivityManagerService的attachApplication函数中。

Step 26. ActivityManagerService.attachApplication

    @Override
    public final void attachApplication(IApplicationThread thread) {
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final long origId = Binder.clearCallingIdentity();
            // 这里将操作转发给attachApplicationLocked函数。
            attachApplicationLocked(thread, callingPid);
            Binder.restoreCallingIdentity(origId);
        }
    }

Step 27. ActivityManagerService.attachApplicationLocked

3、我们知道,AMS创建一个应用进程后,会设置一个超时时间(一般是10秒),如果超过这个时间,应用进程汗没有和AMS交互,则断定该进程创建失败。
所以,应用进程启动后,需要尽快和AMS交互,及调用AMS的attachApplication函数。在该函数内部将调用attachApplicationLocked,所以此处直接分析attachApplicationLocked,
先看其第一阶段工作。
第一阶段工作比较简单:
1)设置代表该应用进程ProcessRecord对象的一些成员变量,如用于和应用进程交互的thread对象、进程调度优先级及oom_adj的值等。
2)从消息队列中撤销PROC_START_TIMEOUT_MSG.
至此,该阶段启动成功,但是这一阶段的工作仅针对进程本身(如设置调度优先级,oom_adj等),还没有涉及和Activity启动相关的内容,这部分工作将在第二阶段完成。
第二阶段: 工作主要是为调用Application的bindApplication做准备

/*正如我们在前面分析时提到的,刚创建的这个进程并不知道自己的历史使命是什么,甚至连自己的进程名都不知道,只能设为<pre-initiallzed>。其实,Android应用进程的历史使命是 AMS在其启动后才赋予它的,这一点和我们理解的一般意义上的进程不太一样。根据之前的介绍,Andorid的组件应该运行在Anroid运行环境中。从OS角度来说,该运行环境需要和一个进程 绑定。所以,创建应用进程这一步只是创建一个能运行Android运行环境的容器,bindApplication的功能就是创建并初始化位于该进程的Anroid运行环境*/
public final void bindApplication()

第三阶段:通知应用进程Activity和Service等组件,其中用于启动Activity的函数是ActivityStack realStartActivityLocked

    private final boolean attachApplicationLocked(IApplicationThread thread,
                                                  int pid) { // 第一阶段 此pid代表调用进程pid
        ProcessRecord app;
        if (pid != MY_PID && pid >= 0) {
            synchronized (mPidsSelfLocked) {
                app = mPidsSelfLocked.get(pid); // 根据pid查找对应的ProcessRecord对象
            }
        } else {
            app = null;
        }
        /*如果该应用进程由AMS启动,则它一定在AMS中有对应的ProcessRecord,读者可以回顾前面创建 应用进程的代码:AMS先创建了一个ProcessRecord对象,然后才发命令给Zygote。 如果此处app为null,则表示AMS没有该进程的记录,故需要“杀死”它 * */
        if (app == null) {
            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
            if (pid > 0 && pid != MY_PID) { // 如果pid大于零,且不是system_server进程,则“杀死”process
                Process.killProcessQuiet(pid);
                //TODO: killProcessGroup(app.info.uid, pid);
            } else {
                try { // 调用ApplicationThread的scheduleExit函数,应用进程完成处理工作后,将退出运行
                    thread.scheduleExit();
                } catch (Exception e) {
                    // Ignore exceptions.
                }
            }
            return false;
        }
        /* 判断app的Thread是否为空,如果不为空,则表示该ProcessRecord对象还未和一个应用进程绑定。 注意,app是根据pid查找到的,如果旧的进程没有被“杀死”,则系统不会重用该pid */
        if (app.thread != null) {
            handleAppDiedLocked(app, true, true);
        }
        final String processName = app.processName;
        try {
            /* 创建一个应用进程“讣告”接受对象。当应用进程退出时,该对象的binderDied将被调用。 这样,AMS就能做相应处理。binderDied函数将在另外一个线程中执行,其内部也会调用 handleAppDiedLocked。假如用户在binderDied被调用之前又启动一个进程, 那么就会出现以上代码中app.thread不为null的情况。这是多线程环境中常出现的情况 */
            AppDeathRecipient adr = new AppDeathRecipient(
                    app, pid, thread);
            thread.asBinder().linkToDeath(adr, 0);
            app.deathRecipient = adr;
        } catch (RemoteException e) {
            app.resetPackageList(mProcessStats);
            startProcessLocked(app, "link fail", processName);
            return false;
        }
        // 设置该进程的调度优先级和oom_adj相关的成员
        app.makeActive(thread, mProcessStats);
        app.curAdj = app.setAdj = -100;
        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
        app.forcingToForeground = null;
        updateProcessForegroundLocked(app, false, false);
        app.hasShownUi = false;
        app.debugging = false;
        app.cached = false;
        app.killedByAm = false;
        // 启动成功,从消息队列中撤销PROC_START_TIMEOUT_MSG消息
        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
        // 第二阶段 systemserver 早就启动完毕,所以normalMode为true
        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
        // 该函数内部将查询(根据进程名,uid确定)PKMS以获取需要运行在该进程中的ContentProvider
        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
        try {
            int testMode = IApplicationThread.DEBUG_OFF;
            if (mDebugApp != null && mDebugApp.equals(processName)) {
                // 处理debug选项
                testMode = mWaitForDebugger
                        ? IApplicationThread.DEBUG_WAIT
                        : IApplicationThread.DEBUG_ON;
                app.debugging = true;
                if (mDebugTransient) {
                    mDebugApp = mOrigDebugApp;
                    mWaitForDebugger = mOrigWaitForDebugger;
                }
            }
            // 处理profile
            String profileFile = app.instrumentationProfileFile;
            ParcelFileDescriptor profileFd = null;
            int samplingInterval = 0;
            boolean profileAutoStop = false;
            if (mProfileApp != null && mProfileApp.equals(processName)) {
                mProfileProc = app;
                profileFile = mProfileFile;
                profileFd = mProfileFd;
                samplingInterval = mSamplingInterval;
                profileAutoStop = mAutoStopProfiler;
            }
            boolean enableOpenGlTrace = false;
            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
                enableOpenGlTrace = true;
                mOpenGlTraceApp = null;
            }
            // If the app is being launched for restore or full backup, set it up specially
            boolean isRestrictedBackupMode = false;
            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
            }
            // dex化对应的apk包
            ensurePackageDexOpt(app.instrumentationInfo != null
                    ? app.instrumentationInfo.packageName
                    : app.info.packageName);
            // 如果设置了设置了Instrumentation类,该类所在的package也需要dex化
            if (app.instrumentationClass != null) {
                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
            }
            ApplicationInfo appInfo = app.instrumentationInfo != null
                    ? app.instrumentationInfo : app.info;
            // 查询该Application使用的CompatibilityInfo
            app.compat = compatibilityInfoForPackageLocked(appInfo);
            if (profileFd != null) { // 用于记录性能文件
                profileFd = profileFd.dup();
            }
            ProfilerInfo profilerInfo = profileFile == null ? null
                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
            // 通过ApplicationThread和应用进程交互,调用其bindApplication函数
            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
                    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) {
            app.resetPackageList(mProcessStats);
            app.unlinkDeathRecipient();
            startProcessLocked(app, "bind fail", processName);
            return false;
        }
        // 从mPersistentStartingProcesses和mProcessesOnHold中删除相关信息
        mPersistentStartingProcesses.remove(app);
        mProcessesOnHold.remove(app);
        boolean badApp = false;
        boolean didSomething = false;
        // See if the top visible activity is waiting to run in this process...
        if (normalMode) {
            try {
                if (mStackSupervisor.attachApplicationLocked(app)) {
                    didSomething = true;
                }
            } catch (Exception e) {
                badApp = true;
            }
        }
        // Find any services that should be running in this process...
        if (!badApp) {
            try {
                didSomething |= mServices.attachApplicationLocked(app, processName);
            } catch (Exception e) {
                badApp = true;
            }
        }
        // Check if a next-broadcast receiver is in this process...
        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
            try {
                didSomething |= sendPendingBroadcastsLocked(app);
            } catch (Exception e) {
                badApp = true;
            }
        }
        // Check whether the next backup agent is in this process...
        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
            try {
                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
                        mBackupTarget.backupMode);
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
                badApp = true;
            }
        }
        if (badApp) {
            /* 如果以上一个组件启动错误,则设置badApp为true。此处将调用handleAppDiedLocked进行处理 */
            app.kill("error during init", true);
            handleAppDiedLocked(app, false, true);
            return false;
        }
        /* 调整进程oom_adj值,didsomething表示在以上流程中是否启动了Activity或其他组件。 如果启动了任一组件,则didsomething为true,读者以后知道,这里的启动只是向应用进程发出对应的指令, 客户端进程是否成功处理还是未知数。基于这种考虑,此处不宜马上调节进程的oom_adj. 读者可简单的把oom_adj看做一种优先级。如果一个应用进程没有运作任何组件,那么当内存出现不足时, 该进程是最先被系统“杀死”的。反之,如果一个应用进程运行的组建越多,那么它就越不易被系统“杀死” 以回收内存。updateOomAdjLocked就是根据该进程中的组件的情况对应调节进程的oom_adj值 */
        if (!didSomething) {
            updateOomAdjLocked();
        }
        return true;
    }

4、bindApplication为应用程序绑定一个Application
ActivityThread.java (frameworks\base\core\java\android\app)

   public final void bindApplication(......) {
        if (services != null) { // 保存AMS传递过来的系统service信息
            // Setup the service cache in the ServiceManager
            ServiceManager.initServiceCache(services);
        }
        // 向主线程消息队列添加SET_CORE_SETTINGS消息
        setCoreSettings(coreSettings);
        IPackageManager pm = getPackageManager();
        android.content.pm.PackageInfo pi = null;
        try {
            pi = pm.getPackageInfo(appInfo.packageName, 0, UserHandle.myUserId());
        } catch (RemoteException e) {
        }
        if (pi != null) {
            boolean sharedUserIdSet = (pi.sharedUserId != null);
            boolean processNameNotDefault =
                    (pi.applicationInfo != null &&
                            !appInfo.packageName.equals(pi.applicationInfo.processName));
            boolean sharable = (sharedUserIdSet || processNameNotDefault);
            // Tell the VMRuntime about the application, unless it is shared
            // inside a process.
            if (!sharable) {
                VMRuntime.registerAppInfo(appInfo.packageName, appInfo.dataDir,
                        appInfo.processName);
            }
        }
        // 创建AppBindData对象,用于保存一些参数
        AppBindData data = new AppBindData();
        data.processName = processName;
        data.appInfo = appInfo;
        data.providers = providers;
        data.instrumentationName = instrumentationName;
        data.instrumentationArgs = instrumentationArgs;
        data.instrumentationWatcher = instrumentationWatcher;
        data.instrumentationUiAutomationConnection = instrumentationUiConnection;
        data.debugMode = debugMode;
        data.enableOpenGlTrace = enableOpenGlTrace;
        data.restrictedBackupMode = isRestrictedBackupMode;
        data.persistent = persistent;
        data.config = config;
        data.compatInfo = compatInfo;
        data.initProfilerInfo = profilerInfo;
        sendMessage(H.BIND_APPLICATION, data);
    }

5、有以上代码可知,ApplicationThread接收到来之AMS的指令后,会将指令中的参数封装到一个数据结构中,然后通过发送消息的方式转交给主线程去处理。
BIND_APPLICATION最终将由handleBindApplication函数处理。该函数并不复杂,但是其中有些点是值得关注的,这些点主要是初始化应用进程的一些参数。
其中最主要的有两点:
1)创建一个Application对象,该对象是本进程中运行的第一个Application
2)如果该进程Application有ContentProvider,则应安装他们
3)ContentProvider的创建于bindApplication函数中,其时机早于其他组建的创建

  private void handleBindApplication(AppBindData data) {
        mBoundApplication = data;
        mConfiguration = new Configuration(data.config);
        mCompatConfiguration = new Configuration(data.config);
        // 初始化性能统计对象
        mProfiler = new Profiler();
        if (data.initProfilerInfo != null) {
            mProfiler.profileFile = data.initProfilerInfo.profileFile;
            mProfiler.profileFd = data.initProfilerInfo.profileFd;
            mProfiler.samplingInterval = data.initProfilerInfo.samplingInterval;
            mProfiler.autoStopProfiler = data.initProfilerInfo.autoStopProfiler;
        }
        logAppLaunchTime(TAG, "handleBindApplication is called"); /// M: It's for debugging App Launch time
        // 设置进程名,从此,之前那个名为“<pre_initialized>”的进程终于有了正式的名字
        Process.setArgV0(data.processName);
        android.ddm.DdmHandleAppName.setAppName(data.processName,
                UserHandle.myUserId());
        // 启动性能统计
        if (mProfiler.profileFd != null) {
            mProfiler.startProfiling();
        }
        // 如果目标SDK版本小于12,则设置AsyncTask使用pool executor,否则使用
        // serialized executor。这些executor涉及java concurrent 类
        if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) {
            AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
        }
        Message.updateCheckRecycle(data.appInfo.targetSdkVersion);
        /*设置时间 */
        TimeZone.setDefault(null);
        /* * 设置语言 */
        Locale.setDefault(data.config.locale);
        /*设置资源及兼容模式 */
        mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo);
        mCurDefaultDisplayDpi = data.config.densityDpi;
        applyCompatConfiguration(mCurDefaultDisplayDpi);
        // 根据传递过来的ApplicationInfo创建一个对应的LoadApk对象
        data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
        /** * 对于系统APK,如果当前系统为userdebug/eng版,则需要使能dropbox的日志记录 */
        if ((data.appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES)
                == 0) {
            mDensityCompatMode = true;
            Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
        }
        updateDefaultDensity();
        final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
        if (!Process.isIsolated()) {
            final File cacheDir = appContext.getCacheDir();
            if (cacheDir != null) {
                // Provide a usable directory for temporary files
                System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
            } else {
                Log.v(TAG, "Unable to initialize \"java.io.tmpdir\" property due to missing cache directory");
            }
            // Use codeCacheDir to store generated/compiled graphics code
            final File codeCacheDir = appContext.getCodeCacheDir();
            if (codeCacheDir != null) {
                setupGraphicsSupport(data.info, codeCacheDir);
            } else {
                Log.e(TAG, "Unable to setupGraphicsSupport due to missing code-cache directory");
            }
        }
        final boolean is24Hr = "24".equals(mCoreSettings.getString(Settings.System.TIME_12_24));
        DateFormat.set24HourTimePref(is24Hr);
        View.mDebugViewAttributes =
                mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0;
        /** * For system applications on userdebug/eng builds, log stack * traces of disk and network access to dropbox for analysis. */
        if ((data.appInfo.flags &
                (ApplicationInfo.FLAG_SYSTEM |
                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) {
            StrictMode.conditionallyEnableDebugLogging();
        }
        /** * Initialize the default http proxy in this process for the reasons we set the time zone. */
        IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
        if (b != null) {
            // In pre-boot mode (doing initial launch to collect password), not
            // all system is up. This includes the connectivity service, so don't
            // crash if we can't get it.
            IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
            try { // 设置HTTP代理消息
                final ProxyInfo proxyInfo = service.getProxyForNetwork(null);
                Proxy.setHttpProxySystemProperty(proxyInfo);
            } catch (RemoteException e) {
            }
        }
        if (data.instrumentationName != null) {
            // 在正常情况下此条件不满足
        } else {
            // 创建Instrumentation对象,在正常情况下都在这个条件下执行
            mInstrumentation = new Instrumentation();
        }
        // 如果package中声明了FLAG_LARGE_HEAP,则可跳过虚拟机的内存限制,放心使用内存
        if ((data.appInfo.flags & ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
            dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
        } else {
            // Small heap, clamp to the current growth limit and let the heap release
            // pages after the growth limit to the non growth limit capacity. b/18387825
            dalvik.system.VMRuntime.getRuntime().clampGrowthLimit();
        }
        // Allow disk access during application and provider setup. This could
        // block processing ordered broadcasts, but later processing would
        // probably end up doing the same disk access.
        final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
        try {
            //创建一个Application,data.info为LoadedApk类型,在其内部会通过Java反射机制
            // 创建一个在该APK AndroidManifest.xml中声明的Application对象
            Application app = data.info.makeApplication(data.restrictedBackupMode, null);
            // mInitialApplication保存该进程中第一个创建的Application
            mInitialApplication = app;
            // 安装package中携带的contentprovider
            if (!data.restrictedBackupMode) {
                List<ProviderInfo> providers = data.providers;
                if (providers != null) {
                    installContentProviders(app, providers);
                    // For process that contains content providers, we want to
                    // ensure that the JIT is enabled "at some point".
                    mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10 * 1000);
                }
            }
            // Do this after providers, since instrumentation tests generally start their
            // test thread at this point, and we don't want that racing.
            try {
                mInstrumentation.onCreate(data.instrumentationArgs);
            } catch (Exception e) {
                throw new RuntimeException(
                        "Exception thrown in onCreate() of "
                                + data.instrumentationName + ": " + e.toString(), e);
            }
            try { // 调用Application的onCraeate函数,做一些初始化工作
                mInstrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
                if (!mInstrumentation.onException(app, e)) {
                    throw new RuntimeException(
                            "Unable to create application " + app.getClass().getName()
                                    + ": " + e.toString(), e);
                }
            }
        } finally {
            StrictMode.setThreadPolicy(savedPolicy);
        }
    }

Step 28. ActivityStack.realStartActivityLocked

    final boolean realStartActivityLocked(ActivityRecord r,
                                          ProcessRecord app, boolean andResume, boolean checkConfig)
            throws RemoteException {
        ......
        // r,是一个ActivityRecord类型的Binder对象,用来作来这个Activity的token值。
        r.app = app;
        ......
        int idx = app.activities.indexOf(r);
        if (idx < 0) {
            app.activities.add(r);
        }
        .....
        try {
            if (app.thread == null) {
                throw new RemoteException();
            }
            List<ResultInfo> results = null;
            List<ReferrerIntent> newIntents = null;
            if (andResume) {
                results = r.results;
                newIntents = r.newIntents;
            }
            // app.thread进入到ApplicationThreadProxy的scheduleLaunchActivity函数中
            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
                    new Configuration(stack.mOverrideConfig), r.compat, r.launchedFromPackage,
                    task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
                    newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
            ......
        } catch (RemoteException e) {
        }
        ......
        return true;
    }

二、ActivityStack realStartActivityLocked 分析
AMS调用完bindApplication后,将通过realStartActivityLocked启动Activity。在此之前,要创建完应用进程并初始化Android运行环境
6.0的代码中已经没有该方法,但是里面包含了两个关键函数,分别是:scheduleLaunchActivity和completeResumeLocked。其中,
scheduleLaunchActivity用于和应用进程交互,通知它启动目标Activity。而completeResumeLocked将继续AMS的处理流程。

Step 29. ApplicationThreadProxy.scheduleLaunchActivity

 public final void scheduleLaunchActivity(......) throws RemoteException {
        Parcel data = Parcel.obtain();
        data.writeInterfaceToken(IApplicationThread.descriptor);
        intent.writeToParcel(data, 0);
        data.writeStrongBinder(token);
        data.writeInt(ident);
        info.writeToParcel(data, 0);
        curConfig.writeToParcel(data, 0);
        if (overrideConfig != null) {
            data.writeInt(1);
            overrideConfig.writeToParcel(data, 0);
        } else {
            data.writeInt(0);
        }
        compatInfo.writeToParcel(data, 0);
        data.writeString(referrer);
        data.writeStrongBinder(voiceInteractor != null ? voiceInteractor.asBinder() : null);
        data.writeInt(procState);
        data.writeBundle(state);
        data.writePersistableBundle(persistentState);
        data.writeTypedList(pendingResults);
        data.writeTypedList(pendingNewIntents);
        data.writeInt(notResumed ? 1 : 0);
        data.writeInt(isForward ? 1 : 0);
        if (profilerInfo != null) {
            data.writeInt(1);
            profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
        } else {
            data.writeInt(0);
        }
        mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null,
                IBinder.FLAG_ONEWAY);
        data.recycle();
    }

这个函数最终通过Binder驱动程序进入到ApplicationThread的scheduleLaunchActivity函数中。

Step 30. ActivityThread.scheduleLaunchActivity

1、ActivityThread.java (frameworks\base\core\java\android\app)

    public final void scheduleLaunchActivity(......) {
        updateProcessState(procState, false);
        ActivityClientRecord r = new ActivityClientRecord();
        ...... // 保存AMS发送过来的参数信息
        // 向主线程发送消息,该消息的处理在handleLaunchActivity中进行
        sendMessage(H.LAUNCH_ACTIVITY, r);
    }

Step 31. ActivityThread.SendMessage

2、frameworks/base/core/java/android/app/ActivityThread.java

    public void handleMessage(Message msg) {
        switch (msg.what) {
            case LAUNCH_ACTIVITY: {
                final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
                // 根据ApplicationInfo得到对应的PakcageInfo
                r.packageInfo = getPackageInfoNoCheck(
                        r.activityInfo.applicationInfo, r.compatInfo);
                // 调用handleLaunchActivity处理
                handleLaunchActivity(r, null);
            } break;

Step 32. H.handleMessage

Step 33. ActivityThread.handleLaunchActivity

Step 34. ActivityThread.performLaunchActivity

Step 35. MainActivity.onCreate

整个应用程序的启动过程要执行很多步骤,但是整体来看,主要分为以下五个阶段:

   一. Step1 - Step 11:Launcher通过Binder进程间通信机制通知ActivityManagerService,它要启动一个Activity;

   二. Step 12 - Step 16:ActivityManagerService通过Binder进程间通信机制通知Launcher进入Paused状态;

   三. Step 17 - Step 24:Launcher通过Binder进程间通信机制通知ActivityManagerService,它已经准备就绪进入Paused状态,于是ActivityManagerService就创建一个新的进程,用来启动一个ActivityThread实例,即将要启动的Activity就是在这个ActivityThread实例中运行;

   四. Step 25 - Step 27:ActivityThread通过Binder进程间通信机制将一个ApplicationThread类型的Binder对象传递给ActivityManagerService,以便以后ActivityManagerService能够通过这个Binder对象和它进行通信;

   五. Step 28 - Step 35:ActivityManagerService通过Binder进程间通信机制通知ActivityThread,现在一切准备就绪,它可以真正执行Activity的启动操作了。

   这样,应用程序的启动过程就介绍完了,它实质上是启动应用程序的默认Activity,
    原文作者:yaoming168
    原文地址: https://blog.csdn.net/yaoming168/article/details/52402963
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞