一文掌握 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 中的相应方法。
相关推荐
长亭外的少年7 小时前
Kotlin 编译失败问题及解决方案:从守护进程到 Gradle 配置
android·开发语言·kotlin
建群新人小猿9 小时前
会员等级经验问题
android·开发语言·前端·javascript·php
1024小神10 小时前
tauri2.0版本开发苹果ios和安卓android应用,环境搭建和最后编译为apk
android·ios·tauri
兰琛10 小时前
20241121 android中树结构列表(使用recyclerView实现)
android·gitee
Y多了个想法11 小时前
RK3568 android11 适配敦泰触摸屏 FocalTech-ft5526
android·rk3568·触摸屏·tp·敦泰·focaltech·ft5526
NotesChapter12 小时前
Android吸顶效果,并有着ViewPager左右切换
android
_祝你今天愉快13 小时前
分析android :The binary version of its metadata is 1.8.0, expected version is 1.5.
android
暮志未晚Webgl14 小时前
109. UE5 GAS RPG 实现检查点的存档功能
android·java·ue5
麦田里的守望者江14 小时前
KMP 中的 expect 和 actual 声明
android·ios·kotlin
Dnelic-14 小时前
解决 Android 单元测试 No tests found for given includes:
android·junit·单元测试·问题记录·自学笔记