Android 源码解析之 应用(Activity)启动流程

我们在Android手机桌面上点击不同的图标,就可以进入到不用的应用中,非常方便。那么,应用顺利启动背后的流程,你知道多少呢?

这种情况下,Android 应用的启动流程大致可以认为就是 Activity 的启动过程。本文基于 Android 7.0 (API 24)源码进行分析,各个版本的源码略有差异,但这块内容的总体思路和框架都是不变的。

1、Launcher启动应用

我们知道,Android 应用是一般由 Launcher(即通常说的桌面)负责启动的。关于 Launcher 的源码分析,可以看我的系列文章 [传送门]。其中用于启动每个应用的 Intent 信息是存储在每个桌面图标 view 绑定的 tag 中的。拿到启动所需信息后,交由 Activity 的 startActivity 去完成启动过程。

public class Launcher extends Activity
        implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,
                   View.OnTouchListener, PageSwitchListener, LauncherProviderChangeListener,
                    MTKUnreadLoader.UnreadCallbacks {
    ......

    private boolean startActivity(View v, Intent intent, Object tag) {
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        ......
        startActivity(intent, optsBundle);
    }
}

2、Activity.startActivity

源码位置:frameworks/base/core/java/android/app/Activity.java

Google原生桌面 Launcher.java 继承自 Activity,进入父类的方法。由 startActivity 又调用了 startActivityForResult 方法,传入 -1 表示不需要Activity结束后的返回结果。

22 行的 mInstrumentation 是 Activity 类的成员对象,类型是 Intrumentation。当需要创建或暂停某个 Activity 时,都需要通过 Instrumentation 来进行具体的操作。后面的源码分析,会经常看到 Intrumentation 的身影。

26 行的 mMainThread 也是 Activity 类的成员对象,类型是 ActivityThread,它代表的是应用程序的主线程。这里通过 mMainThread.getApplicationThread 获得到 ApplicationThread 实例,它是一个 Binder 接口,后面我们会看到 ActivityManagerService 会使用它来和 ActivityThread 来进行进程间通信。

需注意的是,这里的 mInstrumentation 和 mMainThread 对象都还是 Launcher 所在应用进程里的对象。调用 Intrumentation 的 execStartActivity 方法进行下一步操作。

public class Activity extends ContextThemeWrapper
        implements LayoutInflater.Factory2,
        Window.Callback, KeyEvent.Callback,
        OnCreateContextMenuListener, ComponentCallbacks2,
        Window.OnWindowDismissedCallback, WindowControllerCallback {
    ......
    
    public void startActivity(Intent intent, @Nullable Bundle options) {
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            // Note we want to go through this call for compatibility with
            // applications that may have overridden the method.
            startActivityForResult(intent, -1);
        }
    }

    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        if (mParent == null) {
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            if (ar != null) {
                mMainThread.sendActivityResult(
                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                    ar.getResultData());
            }
            ......
        } else {
            ......
        }
    }
    ......
}

3、 Instrumentation.execStartActivity

源码位置:frameworks/base/core/java/android/app/Instrumentation.java

15 行的 ActivityManagerNative.getDefault 返回了与 ActivityManagerService 跨进程通信的接口—— IActivityManager,具体实现类是 ActivityManagerProxy。通过该接口的 startActivity 函数,通知 AMS,我要启动一个新的 Activity 啦!

在 startActivity 传入的参数中,intent.resolveTypeIfNeeded 返回这个 inten t的 MIME 类型,很多应用并没有配置这个参数,因此,本文返回 null。这里的 target 不为 null,但是target.mEmbddedID 为 null,所以这些参数我们不用关注。

调用 ActivityManagerProxy 的 startActivity 方法进行下一步操作。

    public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        Uri referrer = target != null ? target.onProvideReferrer() : null;
        if (referrer != null) {
            intent.putExtra(Intent.EXTRA_REFERRER, referrer);
        }
        if (mActivityMonitors != null) {
            ......
        }
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

4、ActivityManagerProxy.startActivity

ActivityManagerProxy 是 frameworks/base/core/java/android/app/ActivityManagerNative.java 的内部类。

这里的参数比较多,我们先整理一下。从上面的调用可以知道,这里的参数 resolvedType 和resultWho 均为 null;参数 caller 为 ApplicationThread 类型的 Binder 接口;参数 resultTo 为一个 Binder 的远程接口,我们先不关注它;参数 startFlags 为 0,我们也先不关注它;参数 requestCode 为 -1;profilerInfo 的值为 null。

通过 Binder 接口我们就直接跨进程进入到 ActivityManagerService 的 startActivity 函数去了。

    public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
            String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        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);
        if (profilerInfo != null) {
            data.writeInt(1);
            profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
        } else {
            data.writeInt(0);
        }
        if (options != null) {
            data.writeInt(1);
            options.writeToParcel(data, 0);
        } else {
            data.writeInt(0);
        }
        mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
        reply.readException();
        int result = reply.readInt();
        reply.recycle();
        data.recycle();
        return result;
    }

5、ActivityManagerService.startActivity

源码位置:
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

在 18 行中调用了成员对象 mActivityStarter 的 startActivityMayWait 方法。

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

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

6、ActivityStarter.startActivityMayWait

源码位置:
frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java

参数中 outResult 和 config 均为 null,且表达式 (aInfo.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_CANT
_SAVE_STATE) != 0) 为 false,所以忽略一些无关代码。

代码挺长,但要关注的地方主要就几处:
1、解析 Intent 获取 ResolveInfo 对象赋值给 rInfo。详见6.1;
2、调用 startActivityLocked 进行下一步操作,详见6.2。

    final int startActivityMayWait(IApplicationThread caller, int callingUid,
            String callingPackage, Intent intent, String resolvedType,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, IActivityManager.WaitResult outResult, Configuration config,
            Bundle bOptions, boolean ignoreTargetSecurity, int userId,
            IActivityContainer iContainer, TaskRecord inTask) {

        boolean componentSpecified = intent.getComponent() != null;

        // Save a copy in case ephemeral needs it
        final Intent ephemeralIntent = new Intent(intent);
        // Don't modify the client's object!
        intent = new Intent(intent);

        ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
        if (rInfo == null) {
            ......
        }
        // Collect information about the target of the Intent.
        ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);

        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
        ActivityStackSupervisor.ActivityContainer container =
                (ActivityStackSupervisor.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) {
                callingPid = realCallingPid;
                callingUid = realCallingUid;
            } else {
                callingPid = callingUid = -1;
            }

            final ActivityStack stack;
            if (container == null || container.mStack.isOnHomeDisplay()) {
                stack = mSupervisor.mFocusedStack;
            } else {
                stack = container.mStack;
            }
            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) {
                ......
            }

            final ActivityRecord[] outRecord = new ActivityRecord[1];
            int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
                    aInfo, rInfo, voiceSession, voiceInteractor,
                    resultTo, resultWho, requestCode, callingPid,
                    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                    options, ignoreTargetSecurity, componentSpecified, outRecord, container,
                    inTask);

            ......

            final ActivityRecord launchedActivity = mReusedActivity != null
                    ? mReusedActivity : outRecord[0];
            mSupervisor.mActivityMetricsLogger.notifyActivityLaunched(res, launchedActivity);
            return res;
        }
    }
6.1 ActivityStackSupervisor.resolveIntent(解析Intent)

以上 16 行,AppGlobals.getPackageManager() 返回一个Binder接口 —— IPackageManager,通过该接口,调用到了 PackageManagerService 中的 resolveIntent 方法。

该方法主要做了一件事情,就是通过启动 Activity 时传入的 Intent ,拿到目标 Activity 的 ComponentName(即包名和类名)。然后 PMS 通过 ComponentName 生成其对应的 ActivityInfo 对象,该对象中包含了将要启动的 Activity 在 AndroidManifest.xml 配置的属性信息(如启动模式等)。

    ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId) {
        return resolveIntent(intent, resolvedType, userId, 0);
    }

    ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId, int flags) {
        try {
            return AppGlobals.getPackageManager().resolveIntent(intent, resolvedType,
                    PackageManager.MATCH_DEFAULT_ONLY | flags
                    | ActivityManagerService.STOCK_PM_FLAGS, userId);
        } catch (RemoteException e) {
        }
        return null;
    }
6.2 调用 startActivityLocked

以上 60 行,主要就是把一大堆的变量作为参数传入到 startActivityLocked 中进行下一步处理。

7、ActivityStarter.startActivityLocked

又是一个几百行代码的方法,看的我头皮发麻,把跟本章内容无关的内容就先省略了。

首先,从传进来的参数 caller 得到调用者(本文是 Launcher 应用程序)的进程信息,并保存在 ProcessRecord 类型的 callerApp 对象中。前面说过,参数 resultTo 是 Launcher 这个 Activity 里面的一个 Binder 对象,通过它可以获得 Launcher 这个 Activity 的相关信息,保存在 ActivityRecord 类型的 sourceRecord 变量中。

从 45 行开始,是一系列的异常处理,如果传入的参数有问题,将会中断Activity的启动,然后直接退出。然后是权限检查,如果权限检查未通过,同样直接退出,这里就不详细说了。

92 行是重要的一步,新建了一个 ActivityRecord 对象,该对象记录了 Acitivty 的相关信息。

接着,把刚刚创建的 ActivityRecord 对象作为参数,调用 startActivityUnchecked 方法。

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

        ProcessRecord callerApp = null;
        if (caller != null) {
            callerApp = mService.getRecordForAppLocked(caller);
            if (callerApp != null) {
                callingPid = callerApp.pid;
                callingUid = callerApp.info.uid;
            } else {
                err = ActivityManager.START_PERMISSION_DENIED;
            }
        }

        final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;

        ActivityRecord sourceRecord = null;
        ActivityRecord resultRecord = null;
        if (resultTo != null) {
            sourceRecord = mSupervisor.isInAnyStackLocked(resultTo);
            if (sourceRecord != null) {
                if (requestCode >= 0 && !sourceRecord.finishing) {
                    resultRecord = sourceRecord;
                }
            }
        }

        final int launchFlags = intent.getFlags();

        if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
              ......
        }

        //一系列异常判断
        if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
            err = ActivityManager.START_INTENT_NOT_RESOLVED;
        }

        if (err == ActivityManager.START_SUCCESS && aInfo == null) {
            err = ActivityManager.START_CLASS_NOT_FOUND;
        }

        if (err == ActivityManager.START_SUCCESS && sourceRecord != null
            ......
        }

        if (err == ActivityManager.START_SUCCESS && voiceSession != null) {
            ......
        }

        final ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;

        //异常处理
        if (err != START_SUCCESS) {
            if (resultRecord != null) {
                resultStack.sendActivityResultLocked(
                        -1, resultRecord, resultWho, requestCode, RESULT_CANCELED, null);
            }
            ActivityOptions.abort(options);
            return err;
        }
        ......
        
        //权限检查
        // If permissions need a review before any of the app components can run, we
        // launch the review activity and pass a pending intent to start the activity
        // we are to launching now after the review is completed.
        /// M: CTA requirement - permission control
        if (Build.isPermissionReviewRequired() && aInfo != null) {
            if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(
                    aInfo.packageName, userId)) {
                ......
            }
        }

        // If we have an ephemeral app, abort the process of launching the resolved intent.
        // Instead, launch the ephemeral installer. Once the installer is finished, it
        // starts either the intent we resolved here [on install error] or the ephemeral
        // app [on install success].
        if (rInfo != null && rInfo.ephemeralResolveInfo != null) {
            // Create a pending intent to start the intent resolved here.
            ......
        }

        ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
                intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
                requestCode, componentSpecified, voiceSession != null, mSupervisor, container,
                options, sourceRecord);
        if (outActivity != null) {
            outActivity[0] = r;
        }
        ......
        
        try {
            mService.mWindowManager.deferSurfaceLayout();
            err = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
                    true, options, inTask);
        } finally {
            mService.mWindowManager.continueSurfaceLayout();
        }
        postStartActivityUncheckedProcessing(r, err, stack.mStackId, mSourceRecord, mTargetStack);
        return err;
    }

8、ActivityStarter.startActivityUnchecked

该方法主要做了以下操作:

1、第 5 行,首先初始化一些状态值,保存在对应的成员对象中。详见 8.1。

然后 getReusableIntentActivity 方法查找是否有可以重用的 Activity。这里就跟启动模式相关了。如果启动模式不是默认的 standard,那么就可能会有可复用的 ActivityRecord 实例。本文探讨应用第一次启动的流程,所以没有可重用的实例对象,返回 null。

2、第 27 行,新建 TaskRecord 和 ActivityStack ,对启动的Activity进行管理。详见8.2。

3、第 49 行,然后调用到 ActivityStack.startActivityLocked,完成 Activity 启动前的一些操作。详见8.3。

4、第 62 行,通过 resumeFocusedStackTopActivityLocked 继续往下执行。详见8.4

    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {

        setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
                voiceInteractor);
        computeLaunchingTaskFlags();
        computeSourceStack();
        mIntent.setFlags(mLaunchFlags);
        
        mReusedActivity = getReusableIntentActivity();
        if (mReusedActivity != null) {
            ......
        }

        final ActivityStack topStack = mSupervisor.mFocusedStack;
        ......

        boolean newTask = false;
        final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
                ? mSourceRecord.task : null;

        // Should this be considered a new task?
        if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
                && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
            newTask = true;
            setTaskFromReuseOrCreateNewTask(taskToAffiliate);

            if (mSupervisor.isLockTaskModeViolation(mStartActivity.task)) {
                mSupervisor.showLockTaskToast();

                return START_RETURN_LOCK_TASK_MODE_VIOLATION;
            }
            if (!mMovedOtherTask) {
                updateTaskReturnToType(mStartActivity.task, mLaunchFlags, topStack);
            }
        } else if (mSourceRecord != null) {
            ......
        } else if (mInTask != null) {
            ......
        } else {
            ......
        }
        
        mService.grantUriPermissionFromIntentLocked(mCallingUid, mStartActivity.packageName,
                mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.userId);
        
        mTargetStack.mLastPausedActivity = null;
        mTargetStack.startActivityLocked(mStartActivity, newTask, mKeepCurTransition, mOptions);
        
        if (mDoResume) {
            if (!mLaunchTaskBehind) {
                mService.setFocusedActivityLocked(mStartActivity, "startedActivity");
            }

            final ActivityRecord topTaskActivity = mStartActivity.task.topRunningActivityLocked();
            if (!mTargetStack.isFocusable()
                    || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                    && mStartActivity != topTaskActivity)) {
                ......
            } else {
                mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                        mOptions);
            }
        } else {
            mTargetStack.addRecentActivityLocked(mStartActivity);
        }
        ......
        
        return START_SUCCESS;
    }
8.1 ActivityStarter.setInitialState(Activity状态初始化)

setInitialState 方法做了一些状态的初始化工作。将之前创建的 ActivityRecord 对象传递给成员对象 mStartActivity 并保存起来,后面会用到。

然后将一些启动相关的 flag 信息保存到成员变量 mLaunchFlags 中。其中,Activity 的启动模式就是在这里初始化的。我们知道,Activity 一共有四种启动模式,在源码中有三个 boolean 值:mLaunchSingleTop,mLaunchSingleTask 和 mLaunchSingleInstance。如果这几个值都为 false,那么当前的 Activity 就是默认的启动模式 standard。因为应用初始启动时,Activity 肯定是新建的,所以本文不探讨启动模式的设计和实现。

    private void setInitialState(ActivityRecord r, ActivityOptions options, TaskRecord inTask,
            boolean doResume, int startFlags, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
        reset();

        mStartActivity = r;
        mIntent = r.intent;
        mOptions = options;
        mCallingUid = r.launchedFromUid;
        mSourceRecord = sourceRecord;
        mVoiceSession = voiceSession;
        mVoiceInteractor = voiceInteractor;

        mLaunchBounds = getOverrideBounds(r, options, inTask);

        mLaunchSingleTop = r.launchMode == LAUNCH_SINGLE_TOP;
        mLaunchSingleInstance = r.launchMode == LAUNCH_SINGLE_INSTANCE;
        mLaunchSingleTask = r.launchMode == LAUNCH_SINGLE_TASK;
        mLaunchFlags = adjustLaunchFlagsToDocumentMode(
                r, mLaunchSingleInstance, mLaunchSingleTask, mIntent.getFlags());
        mLaunchTaskBehind = r.mLaunchTaskBehind
                && !mLaunchSingleTask && !mLaunchSingleInstance
                && (mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0;

        sendNewTaskResultRequestIfNeeded();
        
        ......
    }
8.2 ActivityStarter.setTaskFromReuseOrCreateNewTask(新建Task和Stack)

这里涉及到 TaskRecord 和 ActivityStack 的概念:

TaskRecord 是记录 ActivityRecord 的栈,一个 TaskRecord 用链表存有若干 ActivityRecord,已后进先出的栈的形式进行管理。AMS 用 TaskRecord 确保 Activity 启动和退出的顺序。 一般默认情况下,一个应用默认只有一个 TaskRecord,属性 taskAffinity 默认为应用的包名。
ActivityStack 是管理这些 TaskRecord 的,它内部以链表的形式存有历史启动的 TaskRecord。

startActivity 时,如果没有添加 FLAG_ACTIVITY_NEW_TASK 的标志位,默认使用当前的 Task 来启动 Activity。本文在启动应用时是加了这个标记位的,那就需要新建 Task 来启动 Activity。变量 newTask 置为 true, 通过 setTaskFromReuseOrCreateNewTask 方法新建 TaskRecord 和 ActivityStack 。

step 1: 首先,通过 computeStackFocus 方法获取到 ActivityStack 对象,赋给成员对象 mTargetStack 。
step 2: 本文的情况没有可复用的 Task,所以 mReuseTask 为 null。通过 createTaskRecord 方法创建 TaskRecord 对象。
step 3: 最后,通过 setTask 函数把 Task 和 Activity 进行关联。

    private void setTaskFromReuseOrCreateNewTask(TaskRecord taskToAffiliate) {
        mTargetStack = computeStackFocus(mStartActivity, true, mLaunchBounds, mLaunchFlags,
                mOptions);

        if (mReuseTask == null) {
            final TaskRecord task = mTargetStack.createTaskRecord(
                    mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId),
                    mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
                    mNewTaskIntent != null ? mNewTaskIntent : mIntent,
                    mVoiceSession, mVoiceInteractor, !mLaunchTaskBehind /* toTop */);
            mStartActivity.setTask(task, taskToAffiliate);
            if (mLaunchBounds != null) {
                final int stackId = mTargetStack.mStackId;
                if (StackId.resizeStackWithLaunchBounds(stackId)) {
                    mService.resizeStack(
                            stackId, mLaunchBounds, true, !PRESERVE_WINDOWS, ANIMATE, -1);
                } else {
                    mStartActivity.task.updateOverrideConfiguration(mLaunchBounds);
                }
            }
        } else {
            ......
        }
    }
8.3 ActivityStack.startActivityLocked

源码地址:frameworks/base/services/core/java/com/android/server/am/ActivityStack.java

根据上面可知,传入的参数 newTask 为 true,所以无关代码本文忽略了。

首先,取出传入参数包含的 task 和 taskId。通过 insertTaskAtTop() 方法,把之前新建的 TaskRecord 对象保存到 ActivityStack 的成员对象 mTaskHistory 中。再通过 WindowManagerService,根据 taskId 把当前的创建的 Task 放到系统任务栈的栈顶。

然后通过 addActivityToTop() 方法把 Activity 对应的 ActivityRecord 对象插入 TaskRecord 对象的内部链表 mActivities 的尾部。

最后,在 Activity 启动完成之前,通过 showStartingWindow() 方法显示启动中的预览窗口。系统在加载 Activity 布局时,会先显示 window 的背景。这就是为什么我们在启动 Activity 时会先显示一下白屏或者黑屏(跟主题有关)的原因,在 Activity 布局加载完毕后再显示内容。所以这个黑白屏其实就是 window 的背景。

    final void startActivityLocked(ActivityRecord r, boolean newTask, boolean keepCurTransition,
            ActivityOptions options) {
        TaskRecord rTask = r.task;
        final int taskId = rTask.taskId;
        if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) {
            // Last activity in task had been removed or ActivityManagerService is reusing task.
            // Insert or replace.
            // Might not even be in.
            insertTaskAtTop(rTask, r);
            mWindowManager.moveTaskToTop(taskId);
        }
        TaskRecord task = null;
        if (!newTask) {
            ......
        }

        ......

        task = r.task;

        task.addActivityToTop(r);
        task.setFrontOfTask();

        r.putInHistory();
        if (!isHomeStack() || numActivities() > 0) {
            // We want to show the starting preview window if we are
            // switching to a new task, or the next activity's process is
            // not currently running.
            boolean showStartingIcon = newTask;
            ProcessRecord proc = r.app;
            if (proc == null) {
                proc = mService.mProcessNames.get(r.processName, r.info.applicationInfo.uid);
            }
            if (proc == null || proc.thread == null) {
                showStartingIcon = true;
            }

            if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
                ......
            } else {
                mWindowManager.prepareAppTransition(newTask
                        ? r.mLaunchTaskBehind
                                ? TRANSIT_TASK_OPEN_BEHIND
                                : TRANSIT_TASK_OPEN
                        : TRANSIT_ACTIVITY_OPEN, keepCurTransition);
                mNoAnimActivities.remove(r);
            }
            addConfigOverride(r, task);
            boolean doShow = true;
            if (newTask) {
                if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
                    resetTaskIfNeededLocked(r, r);
                    doShow = topRunningNonDelayedActivityLocked(null) == r;
                }
            } else if (options != null && options.getAnimationType()
                    == ActivityOptions.ANIM_SCENE_TRANSITION) {
                ......
            }
            if (r.mLaunchTaskBehind) {
                ......
            } else if (SHOW_APP_STARTING_PREVIEW && doShow) {
                ActivityRecord prev = r.task.topRunningActivityWithStartingWindowLocked();
                if (prev != null) {
                    ......
                }
                r.showStartingWindow(prev, showStartingIcon);
            }
        } else {
            ......
        }
    }
8.4 ActivityStackSupervisor.resumeFocusedStackTopActivityLocked

这里只是一个参数的传递,又回到 ActivityStack 对象的 resumeTopActivityUncheckedLocked 方法中。

    boolean resumeFocusedStackTopActivityLocked(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
        if (targetStack != null && isFocusedStack(targetStack)) {
            return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }
        ......
    }

9、ActivityStack.resumeTopActivityUncheckedLocked

这里主要也是参数的传递,调用 resumeTopActivityInnerLocked() 方法。

    boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
        if (mStackSupervisor.inResumeTopActivity) {
            // Don't even start recursing.
            return false;
        }

        boolean result = false;
        try {
            // Protect against recursion.
            mStackSupervisor.inResumeTopActivity = true;
            if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
                mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
                mService.updateSleepIfNeededLocked();
            }
            result = resumeTopActivityInnerLocked(prev, options);
        } finally {
            mStackSupervisor.inResumeTopActivity = false;
        }
        return result;
    }

10、ActivityStack.resumeTopActivityInnerLocked

函数先通过调用 topRunningActivityLocked 函数获得栈顶的 Activity,该 Activity 信息就是在上面的第8节里设置进去的。本文中获取到的就是我们将要启动的 Activity 了,然后保存到 next 变量中。

我们忽略掉几百行代码,直接来到最后,因为第一次启动,next.app 为 null。所以调用 ActivityStackSupervisor 的 startSpecificActivityLocked 方法。这里把刚刚获取的栈顶 Activity 作为参数传入。

    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
        ......

        mStackSupervisor.cancelInitializingActivities();

        // Find the first activity that is not finishing.
        final ActivityRecord next = topRunningActivityLocked();

        // Remember how we'll process this pause/resume situation, and ensure
        // that the state is reset however we wind up proceeding.
        final boolean userLeaving = mStackSupervisor.mUserLeaving;
        mStackSupervisor.mUserLeaving = false;

        final TaskRecord prevTask = prev != null ? prev.task : null;
        if (next == null) {
            ......
        }
        ......
        
        ActivityStack lastStack = mStackSupervisor.getLastStack();
        if (next.app != null && next.app.thread != null) {
            ......
        } else {
            // Whoops, need to restart this activity!
            if (!next.hasBeenLaunched) {
                next.hasBeenLaunched = true;
            } else {
                if (SHOW_APP_STARTING_PREVIEW) {
                    next.showStartingWindow(null, true);
                }
            }
            mStackSupervisor.startSpecificActivityLocked(next, true, true);
        }

        return true;
    }

11、ActivityStackSupervisor.startSpecificActivityLocked

首先,根据进程名(其实就是应用的包名)和 uid,从 AMS 中查找是否有缓存的 ProcessRecord 实例对象。

如果应用已经启动过,那么可以获取到缓存的 ProcessRecord 实例,直接调用 realStartActivityLocked 即可;

但是本文探讨的是应用第一次启动的过程,所以 getProcessRecordLocked 将会返回 null。那么需要先调用 AMS 的 startProcessLocked 创建相应的实例对象。

    void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);

        r.task.stack.setLaunchTime(r);

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

12、ActivityManagerService.startProcessLocked

startProcessLocked 重写了几个入参个数不一样的方法。总的来说,主要做了两件事情:

1、创建 ProcessRecord 实例对象并返回。看到 18 行,前面 isolated 传入的 false,所以先通过 getProcessRecordLocked 获取缓存对象,如果返回 null,再通过 32 行的 newProcessRecordLocked 方法新建一个 ProcessRecord 实例对象,同时将该对象加入缓存,留待下次直接取用;

2、创建了应用的主线程 —— ActivityThread 。ActivityThread 就是我们所说的主线程或者UI线程,一个应用不管有多少 Activity,都只有一个 ActivityThread 实例。
看到 94 行, Process.start 方法中通过调用 ActivityThread.main 方法完成创建。创建完成后,通过 Binder 接口(IActivityManager)调用 AMS 的 attachApplication 方法,把 ActivityThread 端的 Binder 接口实现类(ApplicationThread)作为参数传递给 AMS。AMS 就可以通过这个 Binder 接口,实现与 ActivityThread 通信了。

在 AMS 中,通过 attachApplication —> attachApplicationLocked —> ActivityStackSupervisor.attachApplicationLocked 的调用顺序,最终还是回到了之前所说的 realStartActivityLocked 方法。

    final ProcessRecord startProcessLocked(String processName,
            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
            boolean isolated, boolean keepIfLarge) {
        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
                null /* crashHandler */);
    }


    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
        long startTime = SystemClock.elapsedRealtime();
        ProcessRecord app;
        if (!isolated) {
            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
            checkTime(startTime, "startProcess: after getProcessRecord");

            ......
        } else {
            // If this is an isolated process, it can't re-use an existing process.
            app = 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");
        }

        ......

        checkTime(startTime, "startProcess: stepping in to startProcess");
        startProcessLocked(
                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
        checkTime(startTime, "startProcess: done starting proc!");
        return (app.pid != 0) ? app : null;
    }


    private final void startProcessLocked(ProcessRecord app, String hostingType,
            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
        long startTime = SystemClock.elapsedRealtime();
        if (app.pid > 0 && app.pid != MY_PID) {
            checkTime(startTime, "startProcess: removing from pids map");
            synchronized (mPidsSelfLocked) {
                mPidsSelfLocked.remove(app.pid);
                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
            }
            checkTime(startTime, "startProcess: done removing from pids map");
            app.setPid(0);
        }

        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
                "startProcessLocked removing on hold: " + app);
        mProcessesOnHold.remove(app);

        checkTime(startTime, "startProcess: starting to update cpu stats");
        updateCpuStats();
        checkTime(startTime, "startProcess: done updating cpu stats");

        try {
            try {
                final int userId = UserHandle.getUserId(app.uid);
                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
            } catch (RemoteException e) {
                throw e.rethrowAsRuntimeException();
            }

            ......

            // Start the process.  It will either succeed and return a result containing
            // the PID of the new process, or else throw a RuntimeException.
            boolean isActivityProcess = (entryPoint == null);
            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
                    app.processName);
            checkTime(startTime, "startProcess: asking zygote to start proc");
            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);
            
            ......
        } catch (RuntimeException e) {
            Slog.e(TAG, "Failure starting process " + app.processName, e);
            ......
        }
    }

13、ActivityStackSupervisor.realStartActivityLocked

看到这个方法的命名,是不是留下了激动的泪水?文章分析了大半篇,好像要真正开始启动 Activity 了。

看到 61 行的 scheduleLaunchActivity 方法,调用它的 app.thread 的类型是 IApplicationThread。它继承了 IInterface 接口,是一个 Binder 接口。那么它的实现类是什么呢?答案就是 ActivityThread 中的内部类 ApplicationThread。

    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {

        ......

        final ActivityStack stack = task.stack;
        try {
            if (app.thread == null) {
                throw new RemoteException();
            }
            List<ResultInfo> results = null;
            List<ReferrerIntent> newIntents = null;
            if (andResume) {
                results = r.results;
                newIntents = r.newIntents;
            }

            if (r.isHomeActivity()) {
                // Home process is the root process of the task.
                mService.mHomeProcess = task.mActivities.get(0).app;
            }
            mService.notifyPackageUse(r.intent.getComponent().getPackageName(),
                                      PackageManager.NOTIFY_PACKAGE_USE_ACTIVITY);
            r.sleeping = false;
            r.forceNewConfig = false;
            mService.showUnsupportedZoomDialogIfNeededLocked(r);
            mService.showAskCompatModeDialogLocked(r);
            r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
            ProfilerInfo profilerInfo = null;
            if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
                if (mService.mProfileProc == null || mService.mProfileProc == app) {
                    mService.mProfileProc = app;
                    final String profileFile = mService.mProfileFile;
                    if (profileFile != null) {
                        ParcelFileDescriptor profileFd = mService.mProfileFd;
                        if (profileFd != null) {
                            try {
                                profileFd = profileFd.dup();
                            } catch (IOException e) {
                                if (profileFd != null) {
                                    try {
                                        profileFd.close();
                                    } catch (IOException o) {
                                    }
                                    profileFd = null;
                                }
                            }
                        }

                        profilerInfo = new ProfilerInfo(profileFile, profileFd,
                                mService.mSamplingInterval, mService.mAutoStopProfiler);
                    }
                }
            }

            if (andResume) {
                app.hasShownUi = true;
                app.pendingUiClean = true;
            }
            app.forceProcessStateUpTo(mService.mTopProcessState);
            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
                    new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,
                    task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
                    newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);

            if ((app.info.privateFlags&ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
                // This may be a heavy-weight process!  Note that the package
                // manager will ensure that only activity can run in the main
                // process of the .apk, which is the only thing that will be
                // considered heavy-weight.
                if (app.processName.equals(app.info.packageName)) {
                    mService.mHeavyWeightProcess = app;
                    Message msg = mService.mHandler.obtainMessage(
                            ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
                    msg.obj = r;
                    mService.mHandler.sendMessage(msg);
                }
            }

        } catch (RemoteException e) {
            ,,,,,,
            throw e;
        }

        ......
        return true;
    }

14、ApplicationThread.scheduleLaunchActivity

这里就是发送一个启动 Activity 的消息交由 Handler 去处理。

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

            updateProcessState(procState, false);

            ActivityClientRecord r = new ActivityClientRecord();

            r.token = token;
            r.ident = ident;
            r.intent = intent;
            r.referrer = referrer;
            r.voiceInteractor = voiceInteractor;
            r.activityInfo = info;
            r.compatInfo = compatInfo;
            r.state = state;
            r.persistentState = persistentState;

            r.pendingResults = pendingResults;
            r.pendingIntents = pendingNewIntents;

            r.startsNotResumed = notResumed;
            r.isForward = isForward;

            r.profilerInfo = profilerInfo;

            r.overrideConfig = overrideConfig;
            updatePendingConfiguration(curConfig);

            sendMessage(H.LAUNCH_ACTIVITY, r);
        }
        

15、Handler消息处理

刚刚发送的消息类型为 LAUNCH_ACTIVITY,那么就来到了 handleLaunchActivity 方法。

    private class H extends Handler {

        public void handleMessage(Message msg) {
            switch (msg.what) {
                case LAUNCH_ACTIVITY: {
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
                    final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

                    r.packageInfo = getPackageInfoNoCheck(
                            r.activityInfo.applicationInfo, r.compatInfo);
                    handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;
                case RELAUNCH_ACTIVITY: {
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
                    ActivityClientRecord r = (ActivityClientRecord)msg.obj;
                    handleRelaunchActivity(r);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;
                ......
            }
        }
    }

16、ActivityThread.handleLaunchActivity

终于看到了熟悉的类 —— Activity ,由此可见,performLaunchActivity 最终完成了 Activity 对象的创建和启动过程,然后通过 handleResumeActivity 方法回调 Activity 生命周期中的 onResume 方法。

    private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
        ......

        // Initialize before creating the activity
        WindowManagerGlobal.initialize();

        Activity a = performLaunchActivity(r, customIntent);

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

            if (!r.activity.mFinished && r.startsNotResumed) {
                // The activity manager actually wants this one to start out paused, because it
                // needs to be visible but isn't in the foreground. We accomplish this by going
                // through the normal startup (because activities expect to go through onResume()
                // the first time they run, before their window is displayed), and then pausing it.
                // However, in this case we do -not- need to do the full pause cycle (of freezing
                // and such) because the activity manager assumes it can just retain the current
                // state it has.
                performPauseActivityIfNeeded(r, reason);

                // We need to keep around the original state, in case we need to be created again.
                // But we only do this for pre-Honeycomb apps, which always save their state when
                // pausing, so we can not have them save their state when restarting from a paused
                // state. For HC and later, we want to (and can) let the state be saved as the
                // normal part of stopping the activity.
                if (r.isPreHoneycomb()) {
                    r.state = oldState;
                }
            }
        } else {
            // If there was an error, for any reason, tell the activity manager to stop us.
            try {
                ActivityManagerNative.getDefault()
                    .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                            Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }
    }

17、ActivityThread.performLaunchActivity

其中,performLaunchActivity 方法主要完成了如下几项工作:
1、3~19 行,获取待启动的 Activity 的组件信息;
2、24 行完成了 Activity 实例的创建;
3、41 行完成了 Application 实例的创建;
4、57 行通过 attach 方法完成了 Activity 对象内部一些重要成员对象的赋值;
5、76 行调用 Instrumentation 的 callActivityOnCreate,通知 Activity 已经创建完成,可以回调生命周期了。

    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {

        ActivityInfo aInfo = r.activityInfo;
        if (r.packageInfo == null) {
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        }

        ComponentName component = r.intent.getComponent();
        if (component == null) {
            component = r.intent.resolveActivity(
                mInitialApplication.getPackageManager());
            r.intent.setComponent(component);
        }

        if (r.activityInfo.targetActivity != null) {
            component = new ComponentName(r.activityInfo.packageName,
                    r.activityInfo.targetActivity);
        }

        Activity activity = null;
        try {
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess();
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to instantiate activity " + component
                    + ": " + e.toString(), e);
            }
        }

        try {
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);

            if (activity != null) {
                Context appContext = createBaseContextForActivity(r, activity);
                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                Configuration config = new Configuration(mCompatConfiguration);
                if (r.overrideConfig != null) {
                    config.updateFrom(r.overrideConfig);
                }

                Window window = null;
                if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
                    window = r.mPendingRemoveWindow;
                    r.mPendingRemoveWindow = null;
                    r.mPendingRemoveWindowManager = null;
                }
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window);

                if (customIntent != null) {
                    activity.mIntent = customIntent;
                }
                r.lastNonConfigurationInstances = null;
                activity.mStartedActivity = false;
                int theme = r.activityInfo.getThemeResource();
                if (theme != 0) {
                    activity.setTheme(theme);
                }

                activity.mCalled = false;
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
                ......
            }
            r.paused = true;

            mActivities.put(r.token, r);

        } catch (SuperNotCalledException e) {
            throw e;

        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to start activity " + component
                    + ": " + e.toString(), e);
            }
        }

        return activity;
    }
17.1 Instrumentation.newActivity(通过类加载器新建 Activity 对象)

将需要启动的 Activity 的类名,传入 Instrumentation 对象的 newActivity 方法,通过 类加载器完成了对象的创建。

    public Activity newActivity(ClassLoader cl, String className,
            Intent intent)
            throws InstantiationException, IllegalAccessException,
            ClassNotFoundException {
        return (Activity)cl.loadClass(className).newInstance();
    }
17.2 LoadedApk.makeApplication(创建 Application 对象)

该方法内部主要做了三项工作:
1、24 行创建了 Application 级别的 Context(单例对象里经常需要这个上下文对象);
1、25 行通过类加载器的方式完成 Application 对象的创建;
3、通过 Instrumentation 回调了 Application 的 onCreate 方法。

    public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        if (mApplication != null) {
            return mApplication;
        }

        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");

        Application app = null;

        String appClass = mApplicationInfo.className;
        if (forceDefaultAppClass || (appClass == null)) {
            appClass = "android.app.Application";
        }

        try {
            java.lang.ClassLoader cl = getClassLoader();
            if (!mPackageName.equals("android")) {
                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                        "initializeJavaContextClassLoader");
                initializeJavaContextClassLoader();
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            }
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
            appContext.setOuterContext(app);
        } catch (Exception e) {
            if (!mActivityThread.mInstrumentation.onException(app, e)) {
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                throw new RuntimeException(
                    "Unable to instantiate application " + appClass
                    + ": " + e.toString(), e);
            }
        }
        mActivityThread.mAllApplications.add(app);
        mApplication = app;

        if (instrumentation != null) {
            try {
                instrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
                if (!instrumentation.onException(app, e)) {
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    throw new RuntimeException(
                        "Unable to create application " + app.getClass().getName()
                        + ": " + e.toString(), e);
                }
            }
        }

        ......

        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

        return app;
    }
17.3 Activity.attach(通过 Activity 的 attach 方法完成一些重要成员对象的初始化)

首先,创建了 Activity 级别的 Context 对象;

接着调用了 Activity 中的 attach 方法,主要完成两项工作:
1、通过 attach 方法传入的参数,赋值给了 Activity 对象内部的成员对象,完成了 ActivityThread、ActivityInfo 等重要成员对象的初始化;
2、创建了 Window 对象并与其建立关联,这样触摸事件就可以从 Window 向 Activity 进行传递。

    final void attach(Context context, ActivityThread aThread,
            Instrumentation instr, IBinder token, int ident,
            Application application, Intent intent, ActivityInfo info,
            CharSequence title, Activity parent, String id,
            NonConfigurationInstances lastNonConfigurationInstances,
            Configuration config, String referrer, IVoiceInteractor voiceInteractor,
            Window window) {
        attachBaseContext(context);

        mFragments.attachHost(null /*parent*/);

        mWindow = new PhoneWindow(this, window);
        mWindow.setWindowControllerCallback(this);
        mWindow.setCallback(this);
        mWindow.setOnWindowDismissedCallback(this);
        mWindow.getLayoutInflater().setPrivateFactory(this);
        if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
            mWindow.setSoftInputMode(info.softInputMode);
        }
        if (info.uiOptions != 0) {
            mWindow.setUiOptions(info.uiOptions);
        }
        mUiThread = Thread.currentThread();

        mMainThread = aThread;
        mInstrumentation = instr;
        mToken = token;
        mIdent = ident;
        mApplication = application;
        mIntent = intent;
        mReferrer = referrer;
        mComponent = intent.getComponent();
        mActivityInfo = info;
        mTitle = title;
        mParent = parent;
        mEmbeddedID = id;
        mLastNonConfigurationInstances = lastNonConfigurationInstances;
        if (voiceInteractor != null) {
            if (lastNonConfigurationInstances != null) {
                mVoiceInteractor = lastNonConfigurationInstances.voiceInteractor;
            } else {
                mVoiceInteractor = new VoiceInteractor(voiceInteractor, this, this,
                        Looper.myLooper());
            }
        }

        mWindow.setWindowManager(
                (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
                mToken, mComponent.flattenToString(),
                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
        if (mParent != null) {
            mWindow.setContainer(mParent.getWindow());
        }
        mWindowManager = mWindow.getWindowManager();
        mCurrentConfig = config;
    }
17.4 Instrumentation.callActivityOnCreate

通过 Instrumentation 的 callActivityOnCreate 方法,通知 Activity 准备工作已经完毕,可以进行生命周期的回调了。

    public void callActivityOnCreate(Activity activity, Bundle icicle) {
        prePerformCreate(activity);
        activity.performCreate(icicle);
        postPerformCreate(activity);
    }

18、Activity.performCreate (完成 onCreate 的回调)

看到第 3 行,原来我们熟悉的 onCreate 方法是在这里被调用的。

    final void performCreate(Bundle icicle) {
        restoreHasCurrentPermissionRequest(icicle);
        onCreate(icicle);
        mActivityTransitionState.readState(icicle);
        performCreateCommon();
    }

19、总结

从我们经常使用的 startActivity 方法,到完成目标 Activity 的 onCreate 方法的回调,原来中间经历了这么多波折。篇幅有点长,是不是有点被绕晕了,下面来总结一波。

二话不说,先上一张流程图(画的有点丑,将就一下)。
调用流程图

18.1 应用启动的主要步骤

结合上面的流程图,可以总结出大致的流程:

1、Launcher 通过 Binder 进程间通信机制通知 ActivityManagerService,我要启动一个 Activity 啦;

2、然后 ActivityManagerService 通过内部持有的 ActivityStarter 类型的对象,完成了目标 Activity 启动前的一些准备工作(如上文所说的解析Intent、权限检查,Activity启动顺序管理等);

3、准备工作完成后,通过包名判断当前的应用是否启动过,如果未启动过,则需要执行第4步操作新建一个应用主线程 ActivityThread ;如果曾经启动过,那么 ActivityThread 已经创建了,直接取出之前缓存的实例对象即可,跳过第4步;

4、ActivityThread 创建完成后,通过 Binder 接口通知 ActivityManagerService ,并将 ApplicationThread (用于和 ActivityThread 通信的 Binder 接口实现类)对象传递给 ActivityManagerService 。ActivityManagerService 通过这个Binder 接口,完成了一些绑定操作;

5、ActivityManagerService 通过这个 Binder 接口跨进程通知 ActivityThread 。接着 ActivityThread 就开始 Application 和 Activity 这两个重要实例对象的创建和初始化工作;

6、创建完毕后,即可回调 Activity 的生命周期方法 onCreate,告诉开发者,可以加载布局了。

18.2 启动过程中涉及到的重要类和对象

1、ActivityManagerService:负责系统中所有 Activity 的生命周期。Activity 的创建和销毁都需要通过 AMS 来完成;其实当应用 Crash 或者 ANR 时,也是通过 AMS 去捕获异常,并弹出 Diaog 来提示用户的。

2、ActivityThread:当应用启动之后,会调用 main() 开始运行,开启消息循环队列,这就是传说中的UI线程或者叫主线程。ActivityManagerService 就是通过 ActivityThread,实现对 Activity 的管理;

3、ApplicationThread:本质上是一个 Binder 接口,用于 ActivityManagerService 与 ActivityThread 之间的通信。

4、Instrumentation:从上面的流程图可以发现,Activity 都是通过 Instrumentation 对象与外界进行交互的。每个 Activity 内都有一个对该对象的引用,可以把 Instrumentation 理解为应用进程的忠实干将。ActivityThread 要创建或暂停某个 Activity 时,都需要通过 Instrumentation 来进行具体
的操作。

5、ActivityRecord:每一个启动的 Activity 都对应着一个 ActivityRecord,存储了该 Activity 相关的所有信息。

6、TaskRecord:是记录对应应用的所有 Activity 启动顺序的类,其通过链表的形式保存 ActivityRecord 来实现管理的目的。

7、ActivityStack:管理所有的 TaskRecord。Activity 在 AMS 的栈管理,用来记录未被销毁的 Activity 的先后顺序,状态信息等。通过 ActivityStack 决定是否需要启动新的进程。


文章有点长,能看到最后,说明你稳的一匹。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值