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

来源:互联网 发布:海尔cosmo平台 知乎 编辑:程序博客网 时间:2024/05/29 19:20

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

这里写图片描述

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,
1 0
原创粉丝点击