一文掌握 Activity 的启动原理,基于android-30的源码分析

Android 开发核心总是绕不过那几个模块,与 Android 的相关面试就离不开这个话题,什么,你又要开始讲述 Binder 的定义跟基础了?不不不,今天我们从 Activity 的启动来分析一波其中的代码原理和 ActivityTaskManagerService 进程间的通信过程。

本章所有源码版本基于 android-30

在 app 运行过程中,不管是 Activity 之前的跳转,还是在手机桌面应用中点击一个 icon 启动这个app,最终都是去通过 startActivity 去打开某一个 Activity 页面。我们知道 Android 中的一个 App 就相当于一个进程,所以 startActivity 操作中还需要判断,目标 Activity 的进程是否已经创建,如果没有,则在显示 Activity 之前还需要将进程 Process 提前创建出来。

所以整个 startActivity 的流程分为 4 大部分,也涉及 4 个进程之间的交互:

  1. 应用进程(Launcher)调用 ActivityTaskManagerService 来创建 Activity
  2. ActivityTaskManagerService 到 ApplicationThread 的调用过程
  3. ActivityTaskManagerService 向 Zygote 发送启用应用进程
  4. ActivityThread 启动 Activity 的过程

1. 应用进程(Launcher)调用 ActivityTaskManagerService 阶段

这一过程并不复杂,看下源码中做了哪些操作。

Activity 的 startActivity

最终调用了 startActivityForResult 方法,传入的 -1 表示不需要获取 startActivity 的结果。

typescript 复制代码
    @Override
    public void startActivity(Intent intent) {
        this.startActivity(intent, null);
    }

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

Activity 的 startActivityForResult

具体代码如下所示:

less 复制代码
    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        if (mParent == null) {
            options = transferSpringboardActivityOptions(options);
            // mMainThread.getApplicationThread()获取当前Activity的进程。
            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());
            }
            if (requestCode >= 0) {
                mStartedActivity = true;
            }
            cancelInputsAndStartExitTransition(options);
        } else {
            ...
        }
    }

startActivityForResult 也很简单,调用 Instrumentation.execStartActivity 方法。剩下的交给 Instrumentation 类去处理。

解释说明:

  • Instrumentation 类主要用来监控应用程序与系统交互。
  • mMainThread.getApplicationThread(),这个就是用来实现进程间通信的,具体来说就是 AMS 所在系统进程通知应用程序进程进行的一系列操作。

Instrumentation 的 execStartActivity

方法如下:

java 复制代码
    @UnsupportedAppUsage
    public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        // 前置处理
        try {
            intent.migrateExtraStreamToClipData(who);
            intent.prepareToLeaveProcess(who);
            // ActivityTaskManager.getService() 获取 ActivityTaskManagerService 的实例
            int result = ActivityTaskManager.getService().startActivity(whoThread,
                    who.getBasePackageName(), who.getAttributionTag(), 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;
    }

ActivityTaskManager.getService() 获取 ActivityTaskManagerService 的实例,是使用 ActivityTaskManagerService 来调用其 startActivity 方法。

java 复制代码
    public static IActivityTaskManager getService() {
        return IActivityTaskManagerSingleton.get();
    }

    @UnsupportedAppUsage(trackingBug = 129726065)
    private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
            new Singleton<IActivityTaskManager>() {
                @Override
                protected IActivityTaskManager create() {
                    // "activity_task"
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
                    return IActivityTaskManager.Stub.asInterface(b);
                }
            };

我们来看 getService 方法调用了 IActivityTaskManagerSingleton 的 get 方法,而它是一个 Singleton 类,在重写的 create 方法中获取 Context.ACTIVITY_TASK_SERVICE 的 IBinder 引用,然后转换成 IActivityTaskManager 类型的对象。典型的AIDL的写法,IActivityTaskManager 类是 AIDL 工具在编译时自动生成,要实现进程间通信,服务端也就是 ActivityTaskManagerService 只需要继承 IActivityTaskManager.Stub 类并实现相应的方法就可以了。

通过 AIDL 来调用 ActivityTaskManagerService 的 startActivity 方法,至此,startActivity 的工作重心成功地从进程 Activity 转移到了系统进程 ActivityTaskManagerService 中。

2. ActivityTaskManagerService 到 ApplicationThread 的调用过程

接下来就看下在 ActivityTaskManagerService 中是如何一步一步执行到目标 Activity 进程的。

  1. 综合处理 launchMode 和 Intent 中的 Flag 标志位,并根据处理结果生成一个目标 Activity 的对象(ActivityRecord)。
  2. 判断是否需要为目标 Activity 创建一个新的进程(ProcessRecord)、新的任务栈(TaskRecord)。

接下来就从 ActivityTaskManagerService 的 startActivity 方法开始看起:

ActivityTaskManagerService 的 startActivity

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

    private int startActivityAsUser(IApplicationThread caller, String callingPackage,
            @Nullable String callingFeatureId, Intent intent, String resolvedType,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
        assertPackageMatchesCallingUid(callingPackage);
        // 判断调用者进程是否被隔离,如果 isIsolated 则抛出 SecurityException 异常
        enforceNotIsolatedCaller("startActivityAsUser");
        // 检查调用者权限
        userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
                Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");

        // TODO: Switch to user app stacks here.
        return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
                .setCaller(caller)
                .setCallingPackage(callingPackage)
                .setCallingFeatureId(callingFeatureId)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setStartFlags(startFlags)
                .setProfilerInfo(profilerInfo)
                .setActivityOptions(bOptions)
                .setUserId(userId)
                .execute();
    }

startActivity 和 startActivityAsUser 的主要区别仅在于方法多了一个参数 UserHandle.getCallingUserId(),该方法会获取调用者的 UserId, ActivityTaskManagerService 可以根据这个 UserId 来确定调用者的权限。

最后通过 getActivityStartController().obtainStarter(intent, "startActivityAsUser") 来获取 ActivityStarter 对象,调用 ActivityStarter 的 execute() 方法继续执行启动流程。

scss 复制代码
    int execute() {
        try {
            ...
            int res;
            synchronized (mService.mGlobalLock) {
                ...
                res = executeRequest(mRequest);
                Binder.restoreCallingIdentity(origId);
                ...
            }
        } finally {
            onExecutionComplete();
        }
    }

在 execute() 中,会再次调用其内部的 executeRequest 方法。

ActivityStarter 的 executeRequest

ActivityStarter 是 Android7.0 中新增的类, 它是用来加载Activity的控制类,看名字也想得到它是专门负责一个 Activity 的启动操作。它的主要作用包括解析 Intent、创建 ActivityRecord、如果有可能还要创建 TaskRecord。

executeRequest 是 ActivityStarter 的核心方法,部分实现如下:

java 复制代码
    private int executeRequest(Request request) {
        ... 
        WindowProcessController callerApp = null;
        if (caller != null) {
            // 得到调用进程的信息
            callerApp = mService.getProcessController(caller);
            if (callerApp != null) {
                callingPid = callerApp.getPid();
                callingUid = callerApp.mInfo.uid;
            } else {
                Slog.w(TAG, "Unable to find app for caller " + caller + " (pid=" + callingPid
                        + ") when starting: " + intent.toString());
                err = ActivityManager.START_PERMISSION_DENIED;
            }
        }
        ...    
        //各种错误检查
        ...
        // 检查 intent 防火墙是否屏蔽了该 intent
        boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
                requestCode, callingPid, callingUid, callingPackage, callingFeatureId,
                request.ignoreTargetSecurity, inTask != null, callerApp, resultRecord, resultStack);
        abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
                callingPid, resolvedType, aInfo.applicationInfo);
        abort |= !mService.getPermissionPolicyInternal().checkStartActivity(intent, callingUid,
                callingPackage);

        ... ... 

        // 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.
        if (aInfo != null) {
            if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(
                    aInfo.packageName, userId)) {
                ...
                // 通过 ActivityStackSupervisor 获取 ResolveInfo 信息
                rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0,
                        computeResolveFilterUid(
                                callingUid, realCallingUid, request.filterCallingUid));
                // 通过 ActivityStackSupervisor 获取目标 Activity 信息 
                aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags,
                        null /*profilerInfo*/);
                ...
            }
        }

        if (rInfo != null && rInfo.auxiliaryInfo != null) {
            ...
            // 通过 ActivityStackSupervisor 获取目标 Activity 信息 
            aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
        }
        // 创建 ActivityRecord 对象
        final ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
                callingPackage, callingFeatureId, intent, resolvedType, aInfo,
                mService.getGlobalConfiguration(), resultRecord, resultWho, requestCode,
                request.componentSpecified, voiceSession != null, mSupervisor, checkedOptions,
                sourceRecord);
        mLastStartActivityRecord = r;
        ...

        mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
                request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
                restrictedBgActivity, intentGrants);
        return mLastStartActivityResult;
    }

可以看出获取目标 Activity 信息的操作由 ActivityStackSupervisor 来实现,主要是负责 Activity 所处栈的管理类。

ActivityStackSupervisor 中的 resolveIntent 中实际上是调用系统 PackageManagerService 来获取最佳 Activity。有时候我们通过隐式 Intent 启动 Activity 时,系统中可能存在多个 Activity 可以处理 Intent,此时会弹出一个选择框让用户选择具体需要打开哪一个 Activity 界面,就是此处的逻辑处理结果。

在 executeRequest 方法的最后会调用 startActivityUnchecked 方法来获取启动 Activity 的结果。startActivityUnchecked 方法中采用 startActivityInner 来处理目标 Activity 的信息。

ActivityStarter 的 startActivityInner

scss 复制代码
@VisibleForTesting
    int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, Task inTask,
            boolean restrictedBgActivity, NeededUriGrants intentGrants) {
        setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
                voiceInteractor, restrictedBgActivity);
        // 1. 计算启动 Activity 的 Flag 值
        computeLaunchingTaskFlags();

        ... ...

        // 2. 处理 Task 和 Activity 的进栈操作
        mTargetStack.startActivityLocked(mStartActivity, topStack.getTopNonFinishingActivity(),
                newTask, mKeepCurTransition, mOptions);
        
        // 3. 启动栈中顶部的 Activity
        if (mDoResume) {
            final ActivityRecord topTaskActivity =
                    mStartActivity.getTask().topRunningActivityLocked();
            if (!mTargetStack.isTopActivityFocusable()
                    || (topTaskActivity != null && topTaskActivity.isTaskOverlay()
                    && mStartActivity != topTaskActivity)) {
                ...
                mTargetStack.ensureActivitiesVisible(null /* starting */,
                        0 /* configChanges */, !PRESERVE_WINDOWS);
                mTargetStack.getDisplay().mDisplayContent.executeAppTransition();
            } else {
                ...
                mRootWindowContainer.resumeFocusedStacksTopActivities(
                        mTargetStack, mStartActivity, mOptions);
            }
        }
        mRootWindowContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);
        return START_SUCCESS;
    }

当前方法主要处理了启动 Activity 的 Flag 值、Task 和 Activity 的进栈操作以及启动栈中顶部的 Activity的相应操作,我们具体一步一步分析。

computeLaunchingTaskFlags 方法具体如下:

csharp 复制代码
    private void computeLaunchingTaskFlags() {
        ... 前置处理 Task 和 Intent 的信息

        if (mInTask == null) {
            if (mSourceRecord == null) {
                // 使用 Context 或者 Application 启动 Activity 时,mSourceRecord 为空
                if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 && mInTask == null) {
                    Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
                            "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
                    mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
                }
            } else if (mSourceRecord.launchMode == LAUNCH_SINGLE_INSTANCE) {
                // 初始 Activity 如果是在 SingleInstance 栈中的 Activity,这种需要添加 NEW_TASK 的标识。
                // 因为 SingleInstance 栈只能允许保存一个 Activity。
                mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
                
            } else if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
                // 如果 Launch Mode 设置了 singleTask 或 singleInstance,则也要创建一个新栈。
                mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
            }
        }
    }

这个方法的前置部分处理完 Task 和 Intent 的信息,根据 Task 和 ActivityRecord 的类型来判断如何给目标 Activity 增加相应的启动 Flag。不同的 Flag 决定了启动 Activity 最终会被放置到哪一个 Task 集合中。

ActivityStackSupervisor 的 startActivityLocked

java 复制代码
void startActivityLocked(ActivityRecord r, ActivityRecord focusedTopActivity,
            boolean newTask, boolean keepCurTransition, ActivityOptions options) {
        Task rTask = r.getTask();
        final boolean allowMoveToFront = options == null || !options.getAvoidMoveToFront();
        final boolean isOrhasTask = rTask == this || hasChild(rTask);
        // mLaunchTaskBehind tasks get placed at the back of the task stack.
        if (!r.mLaunchTaskBehind && allowMoveToFront && (!isOrhasTask || newTask)) {
            // Last activity in task had been removed or ActivityManagerService is reusing task.
            // Insert or replace.
            // Might not even be in.
            positionChildAtTop(rTask);
        }
        ...
    }

方法中会调用 positionChildAtTop 方法尝试将 Task 和 Activity 入栈。如果 Activity 是以 newTask 的模式启动或者 TASK 堆栈中不存在该 Task id,则 Task 会重新入栈,并且放在栈的顶部。需要注意的是:Task 先入栈,之后才是 Activity 入栈,它们是包含关系。

RootWindowContainer 的 resumeFocusedStacksTopActivities 和 updateUserStack

在 RootWindowContainer 的 resumeTopActivityUncheckedLocked 方法中经过一系列调用,期间经过ActivityStack 处理、最终代码到了 ActivityStackSupervisor 中的 startSpecificActivity 方法。

ActivityStackSupervisor 的 startSpecificActivity

java 复制代码
    void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
        // 根据进程名称和 Application 的 uid 来判断目标进程是否已经创建,如果没有则代表进程未创建。
        final WindowProcessController wpc =
                mService.getProcessController(r.processName, r.info.applicationInfo.uid);

        boolean knownToBeDead = false;
        if (wpc != null && wpc.hasThread()) {
            try {
                // 执行启动 Activity 的操作
                realStartActivityLocked(r, wpc, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }

            // If a dead object exception was thrown -- fall through to
            // restart the application.
            knownToBeDead = true;
        }

        r.notifyUnknownVisibilityLaunchedForKeyguardTransition();

        final boolean isTop = andResume && r.isTopRunningActivity();
        // 调用 ActivityTaskManagerService 创建 Activity 所在进程。
        mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
    }

根据源码我们发现不管是目标进程是否为新建,最终都会调用 realStartActivityLocked 方法来执行启动 Activity 的操作。

ActivityStackSupervisor 的 realStartActivityLocked

scss 复制代码
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
            boolean andResume, boolean checkConfig) throws RemoteException {
        ...
        try {
            ...
            try {
                ...
                // Activity 的启动交给了事务(Transaction)来完成
                // Create activity launch transaction.
                final ClientTransaction clientTransaction = ClientTransaction.obtain(
                        proc.getThread(), r.appToken);

                final DisplayContent dc = r.getDisplay().mDisplayContent;
                clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                        System.identityHashCode(r), r.info,
                        // TODO: Have this take the merged configuration instead of separate global
                        // and override configs.
                        mergedConfiguration.getGlobalConfiguration(),
                        mergedConfiguration.getOverrideConfiguration(), r.compat,
                        r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
                        r.getSavedState(), r.getPersistentSavedState(), results, newIntents,
                        dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
                        r.assistToken, r.createFixedRotationAdjustmentsIfNeeded()));

                // Set desired final state.
                final ActivityLifecycleItem lifecycleItem;
                if (andResume) {
                    lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
                } else {
                    lifecycleItem = PauseActivityItem.obtain();
                }
                clientTransaction.setLifecycleStateRequest(lifecycleItem);

                // Schedule transaction.
                mService.getLifecycleManager().scheduleTransaction(clientTransaction);

                ...

            } catch (RemoteException e) {
                throw e;
            }
        } finally {
            endDeferResume();
        }
        ...
        return true;
    }

可以看到 Activity 的启动交给了事务(ClientTransaction)来完成。由 ClientTransaction 来创建 Activity 启动事务,并传入 app.thread 参数,并在之后调用 scheduleTransaction 方法来执行 Activity 启动事务。

Activity 启动事务的执行是由 ClientLifecycleManager 来完成的,具体代码如下:

java 复制代码
    void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        final IApplicationThread client = transaction.getClient();
        transaction.schedule();
        if (!(client instanceof Binder)) {
            // If client is not an instance of Binder - it's a remote call and at this point it is
            // safe to recycle the object. All objects used for local calls will be recycled after
            // the transaction is executed on client in ActivityThread.
            transaction.recycle();
        }
    }

可以看出实际上是调用了启动事务 ClientTransaction 的 schedule 方法,而这个 transaction 实际上是在创建 ClientTransaction 时传入的 app.thread 对象,也就是 ApplicationThread。如下所示:

ini 复制代码
    /** Obtain an instance initialized with provided params. */
    public static ClientTransaction obtain(IApplicationThread client, IBinder activityToken) {
        ClientTransaction instance = ObjectPool.obtain(ClientTransaction.class);
        if (instance == null) {
            instance = new ClientTransaction();
        }
        instance.mClient = client;
        instance.mActivityToken = activityToken;

        return instance;
    }

传入的 app.thread 会赋值给 ClientTransaction 的成员变量 mClient,所以 mClient 变量就是 IApplicationThread 对象即 ActivityThread 的内部类 ApplicationThread,其中 ApplicationThread 继承了 IApplicationThread.Stub。 所以事务最终是调用 app.thread 的 scheduleTransaction 执行。这里通过 IApplicationThread 来与应用进程进行 Binder 通信。所以代码回到了 ApplicationThread.ActivityThread 上。

到这为止 startActivity 操作就成功地从 ActivityTaskManagerService 转移到了目标 Activity 中的 ApplicationThread 中,剩下的就是 ActivityTaskManagerService 通过进程间通信机制通知 ApplicationThread 执行 Activity 的生命周期方法。

3. ActivityTaskManagerService 向 Zygote 发送启用应用进程

在之前 ActivityStackSupervisor 的 startSpecificActivity 方法中,我们看到由 ActivityTaskManagerService 的 startProcessAsync 方法来请求启动新的应用进程。仔细查看其中主要是调用了 ActivityManagerService 的 startProcess 方法

ActivityManagerService 的 startProcess

typescript 复制代码
// ActivityManagerInternal 类
/** Starts a given process. */
public abstract void startProcess(String processName, ApplicationInfo info,
        boolean knownToBeDead, boolean isTop, String hostingType, ComponentName hostingName);

// ActivityManagerService 类
@Override
public void startProcess(String processName, ApplicationInfo info, boolean knownToBeDead,
        boolean isTop, String hostingType, ComponentName hostingName) {
    try {
        if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "startProcess:"
                    + processName);
        }
        synchronized (ActivityManagerService.this) {
            // If the process is known as top app, set a hint so when the process is
            // started, the top priority can be applied immediately to avoid cpu being
            // preempted by other processes before attaching the process of top app.
            startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
                    new HostingRecord(hostingType, hostingName, isTop),
                    ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE, false /* allowWhileBooting */,
                    false /* isolated */);
        }
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    }
}

里面主要是 startProcessLocked 方法

java 复制代码
    @GuardedBy("this")
    final ProcessRecord startProcessLocked(String processName,
            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
            HostingRecord hostingRecord, int zygotePolicyFlags, boolean allowWhileBooting,
            boolean isolated, boolean keepIfLarge) {
        return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
                hostingRecord, zygotePolicyFlags, allowWhileBooting, isolated, 0 /* isolatedUid */,
                keepIfLarge, null /* ABI override */, null /* entryPoint */,
                null /* entryPointArgs */, null /* crashHandler */);
    }

根据一系列的调用,最终可以看到是由 ProcessList 中的 startProcess 方法处理,核心是进行到 Process 的 start 方法。

Process 的 start 方法

less 复制代码
    public static ProcessStartResult start(@NonNull final String processClass,
                                           @Nullable final String niceName,
                                           int uid, int gid, @Nullable int[] gids,
                                           int runtimeFlags,
                                           int mountExternal,
                                           int targetSdkVersion,
                                           @Nullable String seInfo,
                                           @NonNull String abi,
                                           @Nullable String instructionSet,
                                           @Nullable String appDataDir,
                                           @Nullable String invokeWith,
                                           @Nullable String packageName,
                                           int zygotePolicyFlags,
                                           boolean isTopApp,
                                           @Nullable long[] disabledCompatChanges,
                                           @Nullable Map<String, Pair<String, Long>>
                                                   pkgDataInfoMap,
                                           @Nullable Map<String, Pair<String, Long>>
                                                   whitelistedDataInfoMap,
                                           boolean bindMountAppsData,
                                           boolean bindMountAppStorageDirs,
                                           @Nullable String[] zygoteArgs) {
        return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
                    runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, packageName,
                    zygotePolicyFlags, isTopApp, disabledCompatChanges,
                    pkgDataInfoMap, whitelistedDataInfoMap, bindMountAppsData,
                    bindMountAppStorageDirs, zygoteArgs);
    }

不难发现 Process 的 start 方法只调用了 ZYGOTE_PROCESS 的 start 方法,ZYGOTE_PROCESS 类是用于保持与 Zygote 进程的通信状态。

ZygoteProcess 中的 start 方法核心是调用了 startViaZygote 方法,在这个方法最后我们发现

scss 复制代码
        synchronized(mLock) {
            // The USAP pool can not be used if the application will not use the systems graphics
            // driver.  If that driver is requested use the Zygote application start path.
            return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
                                              zygotePolicyFlags,
                                              argsForZygote);
        }

这里面的第一个参数调用了openZygoteSocketIfNeeded方法,这里会调用 ZygoteState 的 connect 方法与 Zygote 建立连接。

而 ZygoteProcess 的 zygoteSendArgsAndGetResult 方法主要是将传入的应用进程的启动参数 argsForZygote 写入到 ZygoteState 中。

到此就完成了 ActivityTaskManagerService 向 Zygote 发送启用应用进程。

4. ActivityThread 启动 Activity 的过程

在第三个章节我们分析了 ActivityTaskManagerService 将启动 Activity 的任务作为一个事务 ClientTransaction 去完成,在 ClientLifecycleManager 中会调用 ClientTransaction的schedule() 方法,而 mClient 是一个 IApplicationThread 接口类型,具体实现是 ActivityThread 的内部类 ApplicationThread。因此后续执行 Activity 生命周期的过程都是由 ApplicationThread 指导完成的,而调用 ActivityThread 的 scheduleTransaction 方法,而 ActivityThread 是继承自抽象类 ClientTransactionHandler,ActivityThread 没有重写该方法,所以这里就会调用到 ClientTransactionHandler 的 scheduleTransaction 方法。具体如下:

csharp 复制代码
public abstract class ClientTransactionHandler {
    // Schedule phase related logic and handlers.

    /** Prepare and schedule transaction for execution. */
    void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }
}

调用 sendMessage 方法,向 Handler 中发送了一个 EXECUTE_TRANSACTION 的消息,并且 Message 中的 obj 就是启动 Activity 的事务对象。而这个 Handler 的具体实现是 ActivityThread 中的 mH 对象。源码如下:

scala 复制代码
public final class ActivityThread extends ClientTransactionHandler
        implements ActivityThreadInternal {
    @UnsupportedAppUsage
    final H mH = new H();
    final Executor mExecutor = new HandlerExecutor(mH);

    class H extends Handler {
         public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
                case EXECUTE_TRANSACTION:
                    final ClientTransaction transaction = (ClientTransaction) msg.obj;
                    mTransactionExecutor.execute(transaction);
                    if (isSystem()) {
                        // Client transactions inside system process are recycled on the client side
                        // instead of ClientLifecycleManager to avoid being cleared before this
                        // message is handled.
                        transaction.recycle();
                    }
                    // TODO(lifecycler): Recycle locally scheduled transactions.
                    break;
            }
         }
    }
}

可以看到这个消息被 TransactionExecutor 处理了,执行了其中的 execute 方法

scss 复制代码
    public void execute(ClientTransaction transaction) {
        ...
        executeCallbacks(transaction);

        executeLifecycleState(transaction);
        mPendingActions.clear();
        if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
    }

内部是由 executeCallback 方法处理的

TransactionExecutor 的 executeCallback

ini 复制代码
    @VisibleForTesting
    public void executeCallbacks(ClientTransaction transaction) {
        final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
        ...
        final int size = callbacks.size();
        for (int i = 0; i < size; ++i) {
            final ClientTransactionItem item = callbacks.get(i);
            if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callback: " + item);
            final int postExecutionState = item.getPostExecutionState();
            final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,
                    item.getPostExecutionState());
            if (closestPreExecutionState != UNDEFINED) {
                cycleToPath(r, closestPreExecutionState, transaction);
            }

            item.execute(mTransactionHandler, token, mPendingActions);
            item.postExecute(mTransactionHandler, token, mPendingActions);
            if (r == null) {
                // Launch activity request will create an activity record.
                r = mTransactionHandler.getActivityClient(token);
            }

            if (postExecutionState != UNDEFINED && r != null) {
                // Skip the very last transition and perform it by explicit state request instead.
                final boolean shouldExcludeLastTransition =
                        i == lastCallbackRequestingState && finalState == postExecutionState;
                cycleToPath(r, postExecutionState, shouldExcludeLastTransition, transaction);
            }
        }
    }

这里 callbacks 列表中存放的是第二阶段中 ActivityStackSupervisor 的 realStartActivityLocked 方法

中创建事务时设置进去的。即 LaunchActivityItem 所以这里是执行 LaunchActivityItem 对象的 execute 方法。

LaunchActivityItem 的 execute()

java 复制代码
    @Override
    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
        ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
                mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
                mPendingResults, mPendingNewIntents, mIsForward,
                mProfilerInfo, client, mAssistToken, mFixedRotationAdjustments);
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

其中的 handleLaunchActivity 是不是以及非常熟悉了,终于到了跟 Activity 生命周期相关的方法了,源码中 client 是 ClientTransationHandler 类型,实际实现类就是 ActivityThread。所以我们可以看一下 ActivityThread 中的 handleLaunchActivity 方法了。

ActivityThread 的 handleLaunchActivity

这是一个比较重要的方法,Activity 的生命周期方法就是在这个方法中有序执行,具体如下:

scss 复制代码
    @Override
    public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent) {
        ...
        // 初始化 Activity 的 WindowManager
        if (ThreadedRenderer.sRendererEnabled
                && (r.activityInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
            HardwareRenderer.preload();
        }
        WindowManagerGlobal.initialize();

        // Hint the GraphicsEnvironment that an activity is launching on the process.
        GraphicsEnvironment.hintActivityLaunch();
        // 调用 performLaunchActivity 创建并显示 Activity
        final Activity a = performLaunchActivity(r, customIntent);
        ...
        return a;
    }

可以看到里面最核心的两个方法就是初始化 Activity 的 WindowManager,以及调用 performLaunchActivity 创建并显示 Activity。

ActivityThread 的 performLaunchActivity

java 复制代码
    /**  Core implementation of activity launch. */
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ...
        Activity activity = null;
        try {
            // 通过反射创建目标 Activity 对象
            java.lang.ClassLoader cl = appContext.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            ...
        } catch (Exception e) {
            ...
        }

        try {
            if (activity != null) {
                ...
                // 调用 attach 方法建立 Activity 与 Context 之间的联系,创建 PhoneWindow 对象,并与 Activity 进行关联操作
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window, r.activityConfigCallback,
                        r.assistToken, r.shareableActivityToken);
                ...
                // 通过 Instrumentation 最终调用 Activity 的 onCreate 方法
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
            }
        } catch (Exception e) {
            ...
        }
        return activity;
    }

可以看到在 performLaunchActivity 方法中主要完成下面三件事:

  1. 通过反射创建目标 Activity 对象。
  2. 调用 attach 方法建立 Activity 与 Context 之间的联系,创建 PhoneWindow 对象,并与 Activity 进行关联操作。
  3. 通过 Instrumentation 最终调用 Activity 的 onCreate 方法。

Instrumentation 的 callActivityOnCreate

scss 复制代码
    public void callActivityOnCreate(Activity activity, Bundle icicle) {
        prePerformCreate(activity);
        activity.performCreate(icicle);
        postPerformCreate(activity);
    }

performCreate 中会调用 Activity 的 onCreate。Activity 的启动就完成了。

至此,目标 Activity 已经被成功创建并执行生命周期方法。

总结

不得不说,Android 每一个版本之前源码都是有一些变动的,今天我们分析了基于 android-30 版本的Activity 的启动的实现流程。这一过程主要涉及 4 个进程间的通信过程:

  • 首先 Launcher 进程通过 Binder 调用 ActivityTaskManagerService 的 startActivity 方法。
  • 然后 ActivityTaskManagerService 通过一系列的计算构造目标 Intent,然后在 ActivityStack 与 ActivityStackSupervisor 中处理 Task 和 Activity 的入栈操作。
  • ActivityTaskManagerService 通过 socket 调用向 Zygote 发送启用应用进程来达到创建应用进程的目的。
  • 最后 ActivityTaskManagerService 通过 Binder 机制,调用目标进程中 ApplicationThread 的方法来创建并执行 Activity 生命周期方法,实际上 ApplicationThread 是 ActivityThread 的一个内部类,它的执行最终都调用到了 ActivityThread 中的相应方法。
相关推荐
CV资深专家5 小时前
在 Android 框架中,接口的可见性规则
android
daifgFuture9 小时前
Android 3D球形水平圆形旋转,旋转动态更换图片
android·3d
二流小码农10 小时前
鸿蒙开发:loading动画的几种实现方式
android·ios·harmonyos
爱吃西红柿!11 小时前
fastadmin fildList 动态下拉框默认选中
android·前端·javascript
悠哉清闲12 小时前
工厂模式与多态结合
android·java
大耳猫12 小时前
Android SharedFlow 详解
android·kotlin·sharedflow
火柴就是我13 小时前
升级 Android Studio 后报错 Error loading build artifacts from redirect.txt
android
androidwork14 小时前
掌握 MotionLayout:交互动画开发
android·kotlin·交互
奔跑吧 android14 小时前
【android bluetooth 协议分析 14】【HFP详解 1】【案例一: 手机侧显示来电,但车机侧没有显示来电: 讲解AT+CLCC命令】
android·hfp·aosp13·telecom·ag·hf·headsetclient
Chenyu_31015 小时前
09.MySQL内外连接
android·数据库·mysql