前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Activity启动过程

Activity启动过程

作者头像
八归少年
发布2024-03-11 08:53:20
2660
发布2024-03-11 08:53:20
举报
文章被收录于专栏:program

首语

Activity作为Android四大组件中使用最频繁的组件,也是和用户交互最多的组件,可见它在Android技术体系的核心地位,了解Activity的启动过程可以帮助我们更好的了解Android系统和使用Activity。

Activity启动过程

当一个应用程序启动Activity时,会调用startActivity方法,startActivity方法实现在ContextWrapper中,它继承自Context,调用mBase的startActivity方法,mBase是一个Context对象,它是在attachBaseContext方法中被赋值的,具体类型为ContextImpl,最终实现在ContextImpl类startActivity方法中,后面我们会分析到这部分。

源码路径:frameworks/base/core/java/android/content/ContextWrapper.java

代码语言:javascript
复制
Context mBase;
protected void attachBaseContext(Context base) {
        if (mBase != null) {
            throw new IllegalStateException("Base context already set");
        }
        mBase = base;
}
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
    mBase.startActivity(intent, options);
}

mMainThread类型为ActivityThread,它是当前应用程序进程的主线程。然后调用ActivityThread类的getInstrumentation方法,返回Instrumentation对象。

源码路径:frameworks/base/core/java/android/app/ContextImpl.java

代码语言:javascript
复制
@Override
    public void startActivity(Intent intent, Bundle options) {
        warnIfCallingFromSystemProcess();

        // Calling start activity from outside an activity without FLAG_ACTIVITY_NEW_TASK is
        // generally not allowed, except if the caller specifies the task id the activity should
        // be launched in. A bug was existed between N and O-MR1 which allowed this to work. We
        // maintain this for backwards compatibility.
        final int targetSdkVersion = getApplicationInfo().targetSdkVersion;

        if ((intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) == 0
                && (targetSdkVersion < Build.VERSION_CODES.N
                        || targetSdkVersion >= Build.VERSION_CODES.P)
                && (options == null
                        || ActivityOptions.fromBundle(options).getLaunchTaskId() == -1)) {
            throw new AndroidRuntimeException(
                    "Calling startActivity() from outside of an Activity "
                            + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
                            + " Is this really what you want?");
        }
        mMainThread.getInstrumentation().execStartActivity(
                getOuterContext(), mMainThread.getApplicationThread(), null,
                (Activity) null, intent, -1, options);
    }

源码路径:frameworks/base/core/java/android/app/ActivityThread.java

代码语言:javascript
复制
public Instrumentation getInstrumentation(){
    return mInstrumentation;
}

Instrumentation类主要是用来监控应用程序和系统的交互。首先调用ActivityTaskManager类的getService方法获取对应Service的代理对象,接着调用它的startActivity方法。

源码路径:frameworks/base/core/java/android/app/Instrumentation.java

代码语言:javascript
复制
public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
    	...
        try {
            intent.migrateExtraStreamToClipData(who);
            intent.prepareToLeaveProcess(who);
            int result = ActivityTaskManager.getService().startActivity(whoThread,
                    who.getOpPackageName(), 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;
    }

getService方法调用IActivityTaskManagerSingleton的get方法,IActivityTaskManagerSingleton是一个Singleton类,通过ServiceManager来获取名为"activity_task"的Service引用,然后将其转换为IActivityTaskManager类型的对象,IActivityTaskManager是AIDL工具编译自动生成的,文件路径为:frameworks/base/core/java/android/app/IActivityTaskManager.aidl。为实现进程通信,名为"activity_task"的Service也需要继承IActivityTaskManager并实现相应的方法,这个Service为ActivityTaskManagerService。调用ActivityTaskManagerService的startActivity方法。

源码路径:frameworks/base/core/java/android/app/ActivityTaskManager.java

代码语言:javascript
复制
public static IActivityTaskManager getService() {
        return IActivityTaskManagerSingleton.get();
}
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);
                }
            };

startActivity方法调用startActivityAsUser方法,调用getActivityStartController方法获取ActivityStartController实例执行obtainStarter方法,它返回ActivityStarter实例,ActivityStarter是启动Activity的控制类。然后传递Activity的信息,执行execute方法。

源码路径:

frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

代码语言:javascript
复制
	@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());
    }
	@Override
    public int startActivityAsUser(IApplicationThread caller, String callingPackage,
            String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
            String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
            Bundle bOptions, int userId) {
        return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
                resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
                true /*validateIncomingUser*/);
    }
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) {
		...
        // TODO: Switch to user app stacks here.
        return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
            	//传递Activity信息
                .setCaller(caller)
                .setCallingPackage(callingPackage)
                .setCallingFeatureId(callingFeatureId)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setStartFlags(startFlags)
                .setProfilerInfo(profilerInfo)
                .setActivityOptions(bOptions)
                .setUserId(userId)
                .execute();

    }
ActivityStartController getActivityStartController() {
        return mActivityStartController;
    }

源码路径:

frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java

代码语言:javascript
复制
    ActivityStarter obtainStarter(Intent intent, String reason) {
        return mFactory.obtain().setIntent(intent).setReason(reason);
    }

execute方法会执行startActivityInner方法,startActivityInner方法中做了task相关的计算,以及任务栈是否存在,不存在重新创建,最终调用到RootWindowContainer类的resumeFocusedTasksTopActivities方法中,根据栈顶Activity状态进行不同处理。getFocusedRootTask获取聚焦可见的任务栈,focusedRoot为Task类型,会执行resumeTopActivityUncheckedLocked方法。

源码路径:

frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java

代码语言:javascript
复制
int execute() {
   try {
		...
        res = executeRequest(mRequest);
   }
}
private int executeRequest(Request request) {
    ...
    if (resultTo != null) {
        //ActivityRecord为Activity的描述类,记录Activity所有信息
        sourceRecord = ActivityRecord.isInAnyTask(resultTo);
    }
    mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
               request.voiceInteractor, startFlags, true /* doResume */, checkedOptions,
               inTask, inTaskFragment, restrictedBgActivity, intentGrants);
}
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, Task inTask,
            TaskFragment inTaskFragment, boolean restrictedBgActivity,
            NeededUriGrants intentGrants) {
    ...
    result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, inTaskFragment, restrictedBgActivity,
                    intentGrants);
}
int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, Task inTask,
            TaskFragment inTaskFragment, boolean restrictedBgActivity,
            NeededUriGrants intentGrants) {
    	//初始化Activity的state
		setInitialState(r, options, inTask, inTaskFragment, doResume, startFlags, sourceRecord,
                voiceSession, voiceInteractor, restrictedBgActivity);
		//计算启动task的flag
        computeLaunchingTaskFlags();
		//计算root task
        computeSourceRootTask();   
    	//不存在任务栈重新创建
    	if (mTargetRootTask == null) {
            mTargetRootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags, targetTask,
                    mOptions);
        }
        if (newTask) {
            final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
                    ? mSourceRecord.getTask() : null;
            setNewTask(taskToAffiliate);
        } else if (mAddingToTask) {
            addOrReparentStartingActivity(targetTask, "adding to task");
        }
    	...
        mRootWindowContainer.resumeFocusedTasksTopActivities(mTargetRootTask, mStartActivity, mOptions, 			mTransientLaunch);        
}

源码路径:

frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java

代码语言:javascript
复制
boolean resumeFocusedTasksTopActivities() {
        return resumeFocusedTasksTopActivities(null, null, null);
    }

    boolean resumeFocusedTasksTopActivities(
            Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions) {
        return resumeFocusedTasksTopActivities(targetRootTask, target, targetOptions,
                false /* deferPause */);
    }

    boolean resumeFocusedTasksTopActivities(
            Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions,
            boolean deferPause) {
        ...
        display.forAllRootTasks(rootTask -> {
            //根据栈顶Activity状态进程不同处理
            final ActivityRecord topRunningActivity = rootTask.topRunningActivity();
            //RESUMED状态
            if (rootTask.getDisplayArea().isTopRootTask(rootTask)
                      && topRunningActivity.isState(RESUMED)) {
                  // Kick off any lingering app transitions form the MoveTaskToFront
                  // operation, but only consider the top task and root-task on that
                  // display.
                  rootTask.executeAppTransition(targetOptions);
            } else {
                  resumedOnDisplay[0] |= topRunningActivity.makeActiveIfNeeded(target);
            }
        }
        final Task focusedRoot = display.getFocusedRootTask();                                
        if (focusedRoot != null) {
                 result |= focusedRoot.resumeTopActivityUncheckedLocked(target, targetOptions);
        } else if (targetRootTask == null) {
                result |= resumeHomeActivity(null /* prev */, "no-focusable-task",
                     display.getDefaultTaskDisplayArea());
        }
    }

resumeTopActivityUncheckedLocked方法会调用resumeTopActivityInnerLocked方法,获取TaskFragment实例,调用resumeTopActivity方法。mTaskSupervisor类型为ActivityTaskSupervisor,最终调用startSpecificActivity方法。

源码路径:frameworks/base/services/core/java/com/android/server/wm/Task.java

代码语言:javascript
复制
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
        return resumeTopActivityUncheckedLocked(prev, options, false /* skipPause */);
    }

    @GuardedBy("mService")
    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options,
            boolean deferPause) {
        if (!mAtmService.isBooting() && !mAtmService.isBooted()) {
            // Not ready yet!
            return false;
        }

        final ActivityRecord topActivity = topRunningActivity(true /* focusableOnly */);
        if (topActivity == null) {
            // There are no activities left in this task, let's look somewhere else.
            return resumeNextFocusableActivityWhenRootTaskIsEmpty(prev, options);
        }

        final boolean[] resumed = new boolean[1];
        final TaskFragment topFragment = topActivity.getTaskFragment();
        resumed[0] = topFragment.resumeTopActivity(prev, options, deferPause);
        forAllLeafTaskFragments(f -> {
            if (topFragment == f) {
                return;
            }
            if (!f.canBeResumed(null /* starting */)) {
                return;
            }
            resumed[0] |= f.resumeTopActivity(prev, options, deferPause);
        }, true);
        return resumed[0];
    }

源码路径:

frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java

代码语言:javascript
复制
final boolean resumeTopActivity(ActivityRecord prev, ActivityOptions options,
            boolean deferPause) {
    ...
    mTaskSupervisor.startSpecificActivity(next, true, true);
}

startSpecificActivity中就比较关键了,因为做了进程的判断,如果Activity有对应进程,并且启动。它就会调用realStartActivityLocked方法启动一个普通Activity,如果Activity还没有对应进程或进程没启动,则需要创建或启动Activity对应的应用程序进程,因为Activity必须运行在应用程序进程中,mService实例为ActivityTaskManagerService,调用startProcessAsync方法创建或启动应用程序进程。

源码路径:

frameworks/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java

代码语言:javascript
复制
void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
    	//获取Activity所在的应用程序进程
        final WindowProcessController wpc =
                mService.getProcessController(r.processName, r.info.applicationInfo.uid);

        boolean knownToBeDead = false;
    	//Activity存在进程并且已经启动
        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;
            // Remove the process record so it won't be considered as alive.
            mService.mProcessNames.remove(wpc.mName, wpc.mUid);
            mService.mProcessMap.remove(wpc.getPid());
        }

        r.notifyUnknownVisibilityLaunchedForKeyguardTransition();

        final boolean isTop = andResume && r.isTopRunningActivity();
    	//创建或启动应用程序进程
        mService.startProcessAsync(r, knownToBeDead, isTop,
                isTop ? HostingRecord.HOSTING_TYPE_TOP_ACTIVITY
                        : HostingRecord.HOSTING_TYPE_ACTIVITY);
    }
根Activity(应用程序)启动过程

Launcher启动过程文章中,我们分析了Launcher通过Context类的startActivity方法来启动根Activity。也就是启动应用程序。流程和上述一致,最终来到ActivityTaskManagerService类的startProcessAsync方法进行创建或启动应用程序进程。

startProcessAsync方法中发送了一条消息,通过PooledLambda类的obtainMessage方法创建一条消息并设置线程,Handler处理消息时会运行这个线程,进而执行PooledLambdaImpl类的invoke方法,最终调用OctConsumer的accept方法,accept方法中调用了ActivityManagerInternal类的startProcess方法,传入的ActivityManagerInternal为mAmInternal,而mAmInternal是在onActivityManagerInternalAdded方法中进行赋值的,那是谁调用了这个方法呢?

代码语言:javascript
复制
public void onActivityManagerInternalAdded() {
        synchronized (mGlobalLock) {
            mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
            mUgmInternal = LocalServices.getService(UriGrantsManagerInternal.class);
        }
}
void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop,
            String hostingType) {
        try {
            if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
                Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "dispatchingStartProcess:"
                        + activity.processName);
            }
            // Post message to start process to avoid possible deadlock of calling into AMS with the
            // ATMS lock held.
            final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,
                    mAmInternal, activity.processName, activity.info.applicationInfo, knownToBeDead,
                    isTop, hostingType, activity.intent.getComponent());
            mH.sendMessage(m);
        } finally {
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
        }
    }

源码路径:

frameworks/base/core/java/com/android/internal/util/function/pooled/PooledLambda.java

代码语言:javascript
复制
import static com.android.internal.util.function.pooled.PooledLambdaImpl.acquire;
static <A, B, C, D, E, F, G, H> Message obtainMessage(
            OctConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F, ? super G,
                    ? super H> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7,
            H arg8) {
        synchronized (Message.sPoolSync) {
            //PooledLambdaImpl类的acquire方法获取PooledRunnable
            PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
                    function, 8, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
                    null, null, null, null);
            //设置Message的Runnable
            return Message.obtain().setCallback(callback.recycleOnUse());
        }
    }
public interface OctConsumer<A, B, C, D, E, F, G, H> {
    void accept(A a, B b, C c, D d, E e, F f, G g, H h);
}

源码路径:

frameworks/base/core/java/com/android/internal/util/function/pooled/PooledLambdaImpl.java

代码语言:javascript
复制
@Override
    R invoke(Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7,
            Object a8, Object a9, Object a10, Object a11) {
        ...
        return doInvoke();
    }
private R doInvoke() {
    switch (argCount) {
    	 case 8: {
               switch (returnType) {
                   case LambdaType.ReturnType.VOID: {
                       ((OctConsumer) mFunc).accept(popArg(0), popArg(1),
                               popArg(2), popArg(3), popArg(4),
                               popArg(5), popArg(6), popArg(7));
                       return null;
        ...
    }
}

SystemServer进程启动过程文章中,我们知道ActivityTaskManagerService是在SystemServer类的startBootstrapServices方法中启动的,接着又启动了AMS,通过调用ActivityManagerService类的onStart方法。在start方法可以看到mInternal被添加到LocalServices中,然后将mInternal通过ActivityTaskManagerService的onActivityManagerInternalAdded方法传递给ActivityTaskManagerService,

那看下mInternal对startProcess方法的实现,在ActivityManagerService类创建了一个LocalService内部类,实现了startProcess方法。

startProcess方法中调用startProcessLocked方法,接着调用ProcessList类的startProcessLocked方法,ProcessList类是AMS用来管理进程的。

源码路径:

frameworks/bae/services/core/java/com/android/server/am/ActivityManagerService.java

代码语言:javascript
复制
@Override
public void onStart() {
   mService.start();
}
private void start() {
   //LocalServices添加mInternal
   LocalServices.addService(ActivityManagerInternal.class, mInternal);
   LocalManagerRegistry.addManager(ActivityManagerLocal.class,
            (ActivityManagerLocal) mInternal);
    //ActivityTaskManagerService的onActivityManagerInternalAdded方法传递mInternal
   mActivityTaskManager.onActivityManagerInternalAdded();
   mPendingIntentController.onActivityManagerInternalAdded();
   mAppProfiler.onActivityManagerInternalAdded();
    CriticalEventLog.init();
}
public ActivityManagerService(Context systemContext, ActivityTaskManagerService atm) {
    ...
    mInternal = new LocalService();    
}
public final class LocalService extends ActivityManagerInternal
            implements ActivityManagerLocal {
    	@Override
        public void startProcess(String processName, ApplicationInfo info, boolean knownToBeDead,
                boolean isTop, String hostingType, ComponentName hostingName) {
            try {
                synchronized (ActivityManagerService.this) {
                    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);
            }
        }
}
final ProcessList mProcessList;
final ProcessRecord startProcessLocked(String processName,
            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
            HostingRecord hostingRecord, int zygotePolicyFlags, boolean allowWhileBooting,
            boolean isolated) {
        return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
                hostingRecord, zygotePolicyFlags, allowWhileBooting, isolated, 0 /* isolatedUid */,
                false /* isSdkSandbox */, 0 /* sdkSandboxClientAppUid */,
                null /* sdkSandboxClientAppPackage */,
                null /* ABI override */, null /* entryPoint */,
                null /* entryPointArgs */, null /* crashHandler */);
    }

ProcessList类中对startProcessLocked进行重载,做了大量进程创建前的准备工作,最终调用startProcess方法,对hostingRecord的hostingZygote进行判断,hostingRecord是从ActivityManagerService类的startProcess方法中传递过来的,创建了一个HostingRecord,通过其构造函数可知hostingZygote为REGULAR_ZYGOTE,因此调用Process.start方法去创建应用程序进程。传递进程名(默认为包名),用户id,用户组id等。Process的start方法中调用了ZygoteProcess的start方法。

源码路径:

frameworks/base/services/core/java/com/android/server/am/ProcessList.java

代码语言:javascript
复制
ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
            boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
            int zygotePolicyFlags, boolean allowWhileBooting, boolean isolated, int isolatedUid,
            boolean isSdkSandbox, int sdkSandboxUid, String sdkSandboxClientAppPackage,
            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
    ...
    final boolean success =
                startProcessLocked(app, hostingRecord, zygotePolicyFlags, abiOverride);
}
boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
            int zygotePolicyFlags, String abiOverride) {
        return startProcessLocked(app, hostingRecord, zygotePolicyFlags,
                false /* disableHiddenApiChecks */, false /* disableTestApiChecks */,
                abiOverride);
    }
boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
            int zygotePolicyFlags, boolean disableHiddenApiChecks, boolean disableTestApiChecks,
            String abiOverride) {
    ...
    //获取应用程序进程的用户id
    int uid = app.uid;
    //用户组id进行赋值    
    app.setGids(gids);    
    //应用程序进程的主线程类名
    final String entryPoint = "android.app.ActivityThread";
    return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
                    runtimeFlags, zygotePolicyFlags, mountExternal, seInfo, requiredAbi,
                    instructionSet, invokeWith, startUptime, startElapsedTime);
}
boolean startProcessLocked(HostingRecord hostingRecord, String entryPoint, ProcessRecord app,
            int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags, int mountExternal,
            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
            long startUptime, long startElapsedTime) {
    
    final Process.ProcessStartResult startResult = startProcess(hostingRecord,
                        entryPoint, app,
                        uid, gids, runtimeFlags, zygotePolicyFlags, mountExternal, seInfo,
                        requiredAbi, instructionSet, invokeWith, startUptime);
    handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
                        startSeq, false);
}
private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags,
            int mountExternal, String seInfo, String requiredAbi, String instructionSet,
            String invokeWith, long startTime) {
    ...
     if (hostingRecord.usesWebviewZygote()) {
                startResult = startWebView(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, null, app.info.packageName,
                        app.getDisabledCompatChanges(),
                        new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()});
      } else if (hostingRecord.usesAppZygote()) {
                final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);

                // We can't isolate app data and storage data as parent zygote already did that.
                startResult = appZygote.getProcess().start(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, null, app.info.packageName,
                        /*zygotePolicyFlags=*/ ZYGOTE_POLICY_FLAG_EMPTY, isTopApp,
                        app.getDisabledCompatChanges(), pkgDataInfoMap, allowlistedAppDataInfoMap,
                        false, false,
                        new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()});
      } else {
                regularZygote = true;
                startResult = Process.start(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, invokeWith, app.info.packageName, zygotePolicyFlags,
                        isTopApp, app.getDisabledCompatChanges(), pkgDataInfoMap,
                        allowlistedAppDataInfoMap, bindMountAppsData, bindMountAppStorageDirs,
                        new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()});
      }
}

源码路径:frameworks/base/core/java/android/os/Process.java

代码语言:javascript
复制
public static final ZygoteProcess ZYGOTE_PROCESS = new ZygoteProcess();

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

start方法调用startViaZygote方法,startViaZygote方法保存进程参数,然后调用zygoteSendArgsAndGetResult方法,第一个参数为ZygoteState,由openZygoteSocketIfNeeded方法获取,ZygoteState是ZygoteProcess的内部类,表示与Zygote进程通信的状态,zygoteSendArgsAndGetResult调用attemptZygoteSendArgsAndGetResult方法,将参数写入到ZygoteState中。

Zygote 进程启动过程文章中,我们知道Zygote启动过程中会调用ZygoteServer创建两个server端的socket,然后启动SystemServer进程,最后等待AMS来创建新的应用程序进程。openZygoteSocketIfNeeded方法中,会与Zygote进程建立socket连接,在Zygote 进程启动过程文章中,Zygote启动脚本有多种,根据不同的启动模式建立不同的连接。连接成功后,Zygote进程就会收到创建新的应用程序进程的请求。在Zygote 进程启动过程文章中,有一个startClass,最后反射获取它的main方法,它就是之前我们提到的android.app.ActivityThread,调用了mMethod的invoke方法,ActivityThread类的main方法会被动态调用。应用程序进程创建完成后,进入了Activity Thread的main方法中。

源码路径:frameworks/base/core/java/android/os/ZygoteProcess.java

代码语言:javascript
复制
public final Process.ProcessStartResult start(@NonNull final String processClass,
                                                  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>>
                                                          allowlistedDataInfoList,
                                                  boolean bindMountAppsData,
                                                  boolean bindMountAppStorageDirs,
                                                  @Nullable String[] zygoteArgs) {
        try {
            return startViaZygote(processClass, niceName, uid, gid, gids,
                    runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false,
                    packageName, zygotePolicyFlags, isTopApp, disabledCompatChanges,
                    pkgDataInfoMap, allowlistedDataInfoList, bindMountAppsData,
                    bindMountAppStorageDirs, zygoteArgs);
        ...
}
private Process.ProcessStartResult startViaZygote(@NonNull final String processClass,
                                                      @Nullable final String niceName,
                                                      final int uid, final int gid,
                                                      @Nullable final int[] gids,
                                                      int runtimeFlags, int mountExternal,
                                                      int targetSdkVersion,
                                                      @Nullable String seInfo,
                                                      @NonNull String abi,
                                                      @Nullable String instructionSet,
                                                      @Nullable String appDataDir,
                                                      @Nullable String invokeWith,
                                                      boolean startChildZygote,
                                                      @Nullable String packageName,
                                                      int zygotePolicyFlags,
                                                      boolean isTopApp,
                                                      @Nullable long[] disabledCompatChanges,
                                                      @Nullable Map<String, Pair<String, Long>>
                                                              pkgDataInfoMap,
                                                      @Nullable Map<String, Pair<String, Long>>
                                                              allowlistedDataInfoList,
                                                      boolean bindMountAppsData,
                                                      boolean bindMountAppStorageDirs,
                                                      @Nullable String[] extraArgs)
                                                      throws ZygoteStartFailedEx {
    	//添加进程参数
        ArrayList<String> argsForZygote = new ArrayList<>();
        argsForZygote.add("--runtime-args");
        argsForZygote.add("--setuid=" + uid);
        argsForZygote.add("--setgid=" + gid);
        argsForZygote.add("--runtime-flags=" + runtimeFlags);
        if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
            argsForZygote.add("--mount-external-default");
        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_INSTALLER) {
            argsForZygote.add("--mount-external-installer");
        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_PASS_THROUGH) {
            argsForZygote.add("--mount-external-pass-through");
        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE) {
            argsForZygote.add("--mount-external-android-writable");
        }

        argsForZygote.add("--target-sdk-version=" + targetSdkVersion);

        // --setgroups is a comma-separated list
        if (gids != null && gids.length > 0) {
            final StringBuilder sb = new StringBuilder();
            sb.append("--setgroups=");

            final int sz = gids.length;
            for (int i = 0; i < sz; i++) {
                if (i != 0) {
                    sb.append(',');
                }
                sb.append(gids[i]);
            }
            argsForZygote.add(sb.toString());
            argsForZygote.add(processClass);
            ...
            return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
                                              zygotePolicyFlags,
                                              argsForZygote);
        }
}
private Process.ProcessStartResult zygoteSendArgsAndGetResult(
            ZygoteState zygoteState, int zygotePolicyFlags, @NonNull ArrayList<String> args)
            throws ZygoteStartFailedEx {
    return attemptZygoteSendArgsAndGetResult(zygoteState, msgStr);
}
private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
            ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
    try {
            final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
            final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;
        	//参数写入ZygoteState
            zygoteWriter.write(msgStr);
            zygoteWriter.flush();
            Process.ProcessStartResult result = new Process.ProcessStartResult();
            result.pid = zygoteInputStream.readInt();
            result.usingWrapper = zygoteInputStream.readBoolean();
            if (result.pid < 0) {
                throw new ZygoteStartFailedEx("fork() failed");
            }
            return result;
        } catch (IOException ex) {
            zygoteState.close();
            Log.e(LOG_TAG, "IO Exception while communicating with Zygote - "
                    + ex.toString());
            throw new ZygoteStartFailedEx(ex);
        }
}
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
        try {
            //与Zygote进程建立socket连接
            attemptConnectionToPrimaryZygote();
			//连接Zygote主模式返回的Zygote是否和应用程序进程所需要的ABI匹配
            if (primaryZygoteState.matches(abi)) {
                return primaryZygoteState;
            }
			//不匹配,连接Zygote辅模式
            if (mZygoteSecondarySocketAddress != null) {
                // The primary zygote didn't match. Try the secondary.
                attemptConnectionToSecondaryZygote();
				//连接Zygote辅模式返回的Zygote是否和应用程序进程所需要的ABI匹配	
                if (secondaryZygoteState.matches(abi)) {
                    return secondaryZygoteState;
                }
            }
        } catch (IOException ioe) {
            throw new ZygoteStartFailedEx("Error connecting to zygote", ioe);
        }

        throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
}  
private void attemptConnectionToPrimaryZygote() throws IOException {
        if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
            primaryZygoteState =
                    ZygoteState.connect(mZygoteSocketAddress, mUsapPoolSocketAddress);

            maybeSetApiDenylistExemptions(primaryZygoteState, false);
            maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState);
        }
}
private void attemptConnectionToSecondaryZygote() throws IOException {
        if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
            secondaryZygoteState =
                    ZygoteState.connect(mZygoteSecondarySocketAddress,
                            mUsapPoolSecondarySocketAddress);

            maybeSetApiDenylistExemptions(secondaryZygoteState, false);
            maybeSetHiddenApiAccessLogSampleRate(secondaryZygoteState);
        }
}

ActivityThread的main方法中,创建了一个ActivityThread实例,调用attach方法,进程通信调用ActivityManagerService的attachApplication方法。

源码路径:frameworks\base\core\java\android\app\ActivityThread.java

代码语言:javascript
复制
public static void main(String[] args) {
    ...
    ActivityThread thread = new ActivityThread();
    thread.attach(false, startSeq);
}
private void attach(boolean system, long startSeq) {
    if (!system) {
            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                                    UserHandle.myUserId());
            RuntimeInit.setApplicationObject(mAppThread.asBinder());
            final IActivityManager mgr = ActivityManager.getService();
            try {
                mgr.attachApplication(mAppThread, startSeq);
     ...
         
}

attachApplication方法调用attachApplicationLocked方法,mAtmInternal为ActivityTaskManagerInternal类型,调用attachApplication方法。

源码路径:

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

代码语言:javascript
复制
public ActivityTaskManagerInternal mAtmInternal;
public ActivityManagerService(Context systemContext, ActivityTaskManagerService atm) {
    mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
}
@Override
    public final void attachApplication(IApplicationThread thread, long startSeq) {
        if (thread == null) {
            throw new SecurityException("Invalid application interface");
        }
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final int callingUid = Binder.getCallingUid();
            final long origId = Binder.clearCallingIdentity();
            attachApplicationLocked(thread, callingPid, callingUid, startSeq);
            Binder.restoreCallingIdentity(origId);
        }
}
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
            int pid, int callingUid, long startSeq) {
    ...
    //创建Application
    thread.bindApplication(processName, appInfo,
                        app.sdkSandboxClientAppVolumeUuid, app.sdkSandboxClientAppPackage,
                        providerList, null, profilerInfo, null, null, null, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.isPersistent(),
                        new Configuration(app.getWindowProcessController().getConfiguration()),
                        app.getCompat(), getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial, autofillOptions, contentCaptureOptions,
                        app.getDisabledCompatChanges(), serializedSystemFontMap,
                        app.getStartElapsedTime(), app.getStartUptime());
    if (normalMode) {
            try {
                didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }
}

SystemServer进程启动ActivityTaskManagerService时候会将ActivityTaskManagerInternal添加到LocalServices中,因此,attachApplication方法实现在ActivityTaskManagerService类的LocalService中,调用RootWindowContainer类的attachApplication方法。

源码路径

frameworks\base\services\core\java\com\android\server\wm\ActivityTaskManagerService.java

代码语言:javascript
复制
RootWindowContainer mRootWindowContainer;

@Override
public void onStart() {
       publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
            mService.start();
}
private void start() {
        LocalServices.addService(ActivityTaskManagerInternal.class, mInternal);
}
public ActivityTaskManagerService(Context context) {
    ...
    mInternal = new LocalService();
}
 final class LocalService extends ActivityTaskManagerInternal {
    	@Override
        public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
            synchronized (mGlobalLockWithoutBoost) {
                if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
                    Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "attachApplication:" + wpc.mName);
                }
                try {
                    return mRootWindowContainer.attachApplication(wpc);
                } finally {
                    Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
                }
            }
        } 
 }

forAllRootTasks方法来自WindowContainer类中。

源码路径:

frameworks\base\services\core\java\com\android\server\wm\RootWindowContainer.java

代码语言:javascript
复制
class RootWindowContainer extends WindowContainer<DisplayContent>
        implements DisplayManager.DisplayListener {
    private final AttachApplicationHelper mAttachApplicationHelper = new AttachApplicationHelper();
    ActivityTaskSupervisor mTaskSupervisor;
boolean attachApplication(WindowProcessController app) throws RemoteException {
        try {
            return mAttachApplicationHelper.process(app);
        } finally {
            mAttachApplicationHelper.reset();
        }
    }
private class AttachApplicationHelper implements Consumer<Task>, Predicate<ActivityRecord> {
    boolean process(WindowProcessController app) throws RemoteException {
            mApp = app;
            for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
                //来自WindowContainer类
                getChildAt(displayNdx).forAllRootTasks(this);
                if (mRemoteException != null) {
                    throw mRemoteException;
                }
            }
            if (!mHasActivityStarted) {
                ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
                        false /* preserveWindows */);
            }
            return mHasActivityStarted;
        }
	}
    	@Override
        public void accept(Task rootTask) {
            mTop = rootTask.topRunningActivity();
            rootTask.forAllActivities(this);
        }

        @Override
        public boolean test(ActivityRecord r) {
            ...
            try {
                if (mTaskSupervisor.realStartActivityLocked(r, mApp,
                        mTop == r && r.getTask().canBeResumed(r) /* andResume */,
                        true /* checkConfig */)) {
                    mHasActivityStarted = true;
                }
          	...
            return false;
        }
    }
}

WindowContainer类是一个窗口容器类,它定义了能够直接或者间接以层级结构的形式持有窗口的类的通用功能,它也是WMS(WindowManagerService)的重要基类。mChildren中保存当前WindowContainer持有的所有子容器,列表的顺序也就是子容器出现在屏幕上的顺序,最顶层的子容器位于队尾。

在WMS体系中,一个WindowState对象就代表了一个窗口,持有WindowState类的对象有很多,其中包含ActivityRecord,在WMS中一个ActivityRecord对象就代表一个Activity对象,存放ActivityRecord的是Task类,而存放Task的是TaskDisplayArea类,Task类继承于TaskFragment,因为mChildren中也存在Task,这时forAllRootTasks方法中遍历会调用到Task重写的forAllRootTasks方法,即AttachApplicationHelper类的accept方法。accpet方法中会调用task的forAllActivities方法,因为mChildren中也存在ActivityRecord,这时会调用ActivityRecord重写的forAllActivities方法。即AttachApplicationHelper类的test方法,test方法中会调用到ActivityTaskSupervisor类的realStartActivityLocked方法。

注意:这里涉及到了WMS的基础知识,后续会从代码角度分析WMS,这里了解即可。

源码路径:

frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java

代码语言:javascript
复制
class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<E>
        implements Comparable<WindowContainer>, Animatable, SurfaceFreezer.Freezable,
        InsetsControlTarget {
    protected final WindowList<E> mChildren = new WindowList<E>();
	void forAllRootTasks(Consumer<Task> callback) {
        forAllRootTasks(callback, true /* traverseTopToBottom */);
    }
    void forAllRootTasks(Consumer<Task> callback, boolean traverseTopToBottom) {
        int count = mChildren.size();
        if (traverseTopToBottom) {
            for (int i = count - 1; i >= 0; --i) {
                mChildren.get(i).forAllRootTasks(callback, traverseTopToBottom);
            }
        } else {
            for (int i = 0; i < count; i++) {
                mChildren.get(i).forAllRootTasks(callback, traverseTopToBottom);
                int newCount = mChildren.size();
                i -= count - newCount;
                count = newCount;
            }
        }
    }
    boolean forAllActivities(Predicate<ActivityRecord> callback) {
        return forAllActivities(callback, true /*traverseTopToBottom*/);
    }
    boolean forAllActivities(Predicate<ActivityRecord> callback, boolean traverseTopToBottom) {
        if (traverseTopToBottom) {
            for (int i = mChildren.size() - 1; i >= 0; --i) {
                if (mChildren.get(i).forAllActivities(callback, traverseTopToBottom)) return true;
            }
        } else {
            final int count = mChildren.size();
            for (int i = 0; i < count; i++) {
                if (mChildren.get(i).forAllActivities(callback, traverseTopToBottom)) return true;
            }
        }

        return false;
    }
}

源码路径:frameworks/base/services/core/java/com/android/server/wm/Task.java

代码语言:javascript
复制
class Task extends TaskFragment {
    @Override
    void forAllRootTasks(Consumer<Task> callback, boolean traverseTopToBottom) {
        if (isRootTask()) {
            callback.accept(this);
        }
    }
}
//frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java
void addChild(ActivityRecord r) {
        addChild(r, POSITION_TOP);
    }

源码路径:

frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java

代码语言:javascript
复制
	@Override
    boolean forAllActivities(Predicate<ActivityRecord> callback, boolean traverseTopToBottom) {
        return callback.test(this);
    }

到这里,就和前面启动普通Activity的方法realStartActivityLocked接轨了,和普通Activity的启动过程一致。

普通Activity的启动过程

realStartActivityLocked方法中,首先创建ClientTransaction,然后创建LaunchActivityItem,添加到ClientTransaction回调中,LaunchActivityItem继承于ClientTransactionItem,然后调用ActivityTaskManagerService类的getLifecycleManager方法,返回ClientLifecycleManager实例再调用scheduleTransaction方法,执行创建的clientTransaction。

代码语言:javascript
复制
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
            boolean andResume, boolean checkConfig) throws RemoteException {
  				...
				// Create activity launch transaction.
                final ClientTransaction clientTransaction = ClientTransaction.obtain(
                        proc.getThread(), r.token);

                final boolean isTransitionForward = r.isTransitionForward();
                final IBinder fragmentToken = r.getTaskFragment().getFragmentToken();
    			//创建LaunchActivityItem
                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.getFilteredReferrer(r.launchedFromPackage), task.voiceInteractor,
                        proc.getReportedProcState(), r.getSavedState(), r.getPersistentSavedState(),
                        results, newIntents, r.takeOptions(), isTransitionForward,
                        proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController,
                        r.shareableActivityToken, r.getLaunchedFromBubble(), fragmentToken));

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

                // 执行transtion.
                mService.getLifecycleManager().scheduleTransaction(clientTransaction);
    			...
}
代码语言:javascript
复制
ClientLifecycleManager getLifecycleManager() {
        return mLifecycleManager;
    }

scheduleTransaction方法又调用了ClientTransaction的schedule方法。

源码路径:

frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java

代码语言:javascript
复制
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        final IApplicationThread client = transaction.getClient();
        transaction.schedule();
        if (!(client instanceof Binder)) {
            transaction.recycle();
        }
    }

mClient类型为IApplicationThread,它是在创建clientTransaction时传入的,和前面提到的一样,它是AIDL工具编译自动生成的,文件路径为:frameworks/base/core/java/android/app/IApplicationThread.aidl,为了进程间通信对应的ApplicationThread需要继承它并实现相应的方法。ApplicationThread是Activity Thread的内部类。

源码路径:

frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java

代码语言:javascript
复制
private IApplicationThread mClient;
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;
    }
public void schedule() throws RemoteException {
        mClient.scheduleTransaction(this);
    }

调用ActivityThread类的scheduleTransaction方法,实现在父类ClientTransactionHandler中。发送了一条消息,Handler实现在ActivityThread类中,mTransactionExecutor类型为TransactionExecutor,调用其execute方法。

源码路径:frameworks/base/core/java/android/app/ActivityThread.java

代码语言:javascript
复制
public final class ActivityThread extends ClientTransactionHandler
        implements ActivityThreadInternal {
    
   private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);
    
   private class ApplicationThread extends IApplicationThread.Stub {
    @Override
        public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
            ActivityThread.this.scheduleTransaction(transaction);
        }
  } 
    @Override
    TransactionExecutor getTransactionExecutor() {
        return mTransactionExecutor;
    }
}
 class H extends Handler {
      public void handleMessage(Message msg) {
          ...
          case EXECUTE_TRANSACTION:
                final ClientTransaction transaction = (ClientTransaction) msg.obj;
                mTransactionExecutor.execute(transaction);
      }
 }

源码路径:frameworks/base/core/java/android/app/ClientTransactionHandler.java

代码语言:javascript
复制
 void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }

execute方法会调用executeCallbacks方法,然后通过ClientTransaction类的getCallbacks方法获取LaunchActivityItem集合,然后调用LaunchActivityItem类的execute和postExecute方法。

源码路径:

frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java

代码语言:javascript
复制
public TransactionExecutor(ClientTransactionHandler clientTransactionHandler) {
        mTransactionHandler = clientTransactionHandler;
}
public void execute(ClientTransaction transaction) {
        if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Start resolving transaction");
    	...
        executeCallbacks(transaction);

        executeLifecycleState(transaction);
        mPendingActions.clear();
        if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
    }
public void executeCallbacks(ClientTransaction transaction) {
    	//获取LaunchActivityItem集合
        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);
            }
			//处理启动Activity
            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);
            }
        }
    }

execute方法创建了ActivityClientRecord对象,client类型为ActivityThread,因为创建TransactionExecutor上下文是ActivityThread,然后调用ActivityThread类的handleLaunchActivity。

源码路径:

frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java

代码语言:javascript
复制
public class LaunchActivityItem extends ClientTransactionItem {
    @Override
    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
        //创建ActivityClientRecord
        ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
                mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
                mPendingResults, mPendingNewIntents, mActivityOptions, mIsForward, mProfilerInfo,
                client, mAssistToken, mShareableActivityToken, mLaunchedFromBubble,
                mTaskFragmentToken);
        //处理启动Activity
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

    @Override
    public void postExecute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        //启动Activity数量
        client.countLaunchingActivities(-1);
    }
}

handleLaunchActivity方法中调用performLaunchActivity方法,它是真正启动Activity的方法,首先创建了appContext,通过类加载器创建Activity,创建Application,调用Activity的attach方法将一些数据如context传递给Activity。

Activity Context具体类型为ContextImpl,Activity类的attach方法中调用了attachBaseContext方法给ContextWrapper类中的mBase赋值,这就验证了开始说到的为什么startActivity的最终实现在ContextImpl类中。

最后开始Activity的第一个生命周期方法onCreate,调用Instrumentation类的callActivityOnCreate方法,最终调用Activity类的performCreate方法,在performCreate方法中会调用Activity的onCreate方法,到这里,Activity就被启动了。

代码语言:javascript
复制
	@Override
    public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent) {
         ...
         //真正启动Activity的方法
         final Activity a = performLaunchActivity(r, customIntent);
        return a;
    }
private ContextImpl createBaseContextForActivity(ActivityClientRecord r) {
        final int displayId = ActivityClient.getInstance().getDisplayId(r.token);
        ContextImpl appContext = ContextImpl.createActivityContext(
                this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig);
		...
        return appContext;
    }
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);
        }
		//app context创建,这里也可以证明Activity Context具体类型为ContextImpl
        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            //类加载器创建Activity
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess(isProtectedComponent(r.activityInfo),
                    appContext.getAttributionSource());
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
		...
        try {
            //有则缓存读取Application,没有创建Application
            Application app = r.packageInfo.makeApplicationInner(false, mInstrumentation);
            synchronized (mResourcesManager) {
                mActivities.put(r.token, r);
            }

            if (activity != null) {
                CharSequence ,title = r.activityInfo.loadLabel(appContext.getPackageManager());
                Configuration config =
                        new Configuration(mConfigurationController.getCompatConfiguration());
                if (r.overrideConfig != null) {
                    config.updateFrom(r.overrideConfig);
                }
                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
                        + r.activityInfo.name + " with config " + config);
                Window window = null;
                if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
                    window = r.mPendingRemoveWindow;
                    r.mPendingRemoveWindow = null;
                    r.mPendingRemoveWindowManager = null;
                }

                // Activity resources must be initialized with the same loaders as the
                // application context.
                appContext.getResources().addLoaders(
                        app.getResources().getLoaders().toArray(new ResourcesLoader[0]));

                appContext.setOuterContext(activity);
                //appContext传递给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);

                if (customIntent != null) {
                    activity.mIntent = customIntent;
                }
                r.lastNonConfigurationInstances = null;
                checkAndBlockForNetworkAccess();
                activity.mStartedActivity = false;
                int theme = r.activityInfo.getThemeResource();
                //设置主题
                if (theme != 0) {
                    activity.setTheme(theme);
                }
                r.activity = activity;
                //调用Activity的onCreate回调,进入Activity生命周期的onCreate阶段
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
            }
            //设置Activity的state为onCreate,
            r.setState(ON_CREATE);
        return activity;
    }
代码语言:javascript
复制
public void callActivityOnCreate(Activity activity, Bundle icicle,
            PersistableBundle persistentState) {
        prePerformCreate(activity);
        activity.performCreate(icicle, persistentState);
        postPerformCreate(activity);
    }

源码路径:frameworks/base/core/java/android/app/Activity.java

代码语言:javascript
复制
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, ActivityConfigCallback activityConfigCallback, IBinder assistToken,
            IBinder shareableActivityToken) {
    		//mBase赋值
            attachBaseContext(context);
}
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
    ...
    if (persistentState != null) {
         onCreate(icicle, persistentState);
    } else {
         onCreate(icicle)
    }
}
进程调用

根Activity(应用)启动过程中进程调用时序图如下。普通Activity只涉及AMS所在进程(Systemserver)和应用程序进程

补充

消息循环创建过程

创建应用程序进程后,进入ActivityThread类的main方法,main方法中首先创建主线程Looper,然后判断Handler类型的sMainThreadHandler是否为null,为null则获取H类,H类继承于Handler,是ActivityThread的内部类,用于处理主线程的消息循环。H类的handleMessage方法中可以发现做了大量生命周期的处理工作,因此可以看出Activity 生命周期不过就是Looper传递消息中的某一个而已。最后调用Looper的loop方法,使得Looper开始处理消息。Looper类的loop方法中存在一个死循环。

可以看出,系统在应用程序进程启动完成后就会创建一个消息循环,这样运行在应用程序进程中的应用程序可以方便的使用消息处理机制。

源码路径:frameworks\base\core\java\android\app\ActivityThread.java

代码语言:javascript
复制
static volatile Handler sMainThreadHandler;
final H mH = new H();
public static void main(String[] args) {
    	...
        //创建主线程Looper
        Looper.prepareMainLooper();
		ActivityThread thread = new ActivityThread();
        thread.attach(false, startSeq);

        if (sMainThreadHandler == null) {
            //绑定主线程H类
            sMainThreadHandler = thread.getHandler();
        }

        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }

        // End of event ActivityThreadMain.
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    	//Looper开始工作
        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");    
}
public Handler getHandler() {
        return mH;
}
class H extends Handler {
    ...
	public void handleMessage(Message msg) {
        case RELAUNCH_ACTIVITY:
                    handleRelaunchActivityLocally((IBinder) msg.obj);
         case EXIT_APPLICATION:
                    if (mInitialApplication != null) {
                        mInitialApplication.onTerminate();
                    }
                    Looper.myLooper().quit();
                    break;
        ...
    }
}

源码路径:frameworks\base\core\java\android\os\Looper.java

代码语言:javascript
复制
final MessageQueue mQueue;
public static void loop() {
    ...
    for (;;) {
            if (!loopOnce(me, ident, thresholdOverride)) {
                return;
            }
        }
}
private static boolean  loopOnce(final Looper me,
            final long ident, final int thresholdOverride) {
     //MessageQueue消息队列中取消息,没有消息时,MessageQueue的next方法会阻塞(next方法也存在死循环)
     Message msg = me.mQueue.next(); // might block
     ...
     //处理消息, msg.target为发送消息的Handler对象
     msg.target.dispatchMessage(msg);
}

这里衍生出两个问题:

主线程 Looper.loop() 死循环为何不会ANR

loop方法中当没有消息的时候才会return,然后就会抛出RuntimeException,主线程就会退出,也意味着应用退出了,在没有消息的时候,MessageQueue的next方法会阻塞,因为next方法内部也存在一个死循环,所以正常情况下应用不会退出。

至于为何不会ANR呢?以下四种场景会导致ANR:

InputDispatching Timeout:5秒内无法响应屏幕触摸事件或键盘输入事件。 BroadcastQueue Timeout :在执行前台广播(BroadcastReceiver)的onReceive()函数时10秒没有处理完成,后台为60秒。 Service Timeout:前台服务20秒内,后台服务在200秒内没有执行完毕。 ContentProvider Timeout :ContentProvider的publish在10s内没进行完。

从代码逻辑可以看出来,我们的代码是在循环内执行的,只能说对消息的处理阻塞了loop方法循环,而不是loop方法循环阻塞了它。这里需要注意循环内消息处理时间过长,才会造成ANR,死循环本身不会造成ANR。

Looper.loop()死循环为何不会导致CPU占用率过高

next方法也存在一个死循环,并且会调用JNI方法nativePollOnce。它对应的C函数为android_os_MessageQueue_nativePollOnce

源码路径:frameworks\base\core\java\android\os\MessageQueue.java

代码语言:javascript
复制
private native void nativePollOnce(long ptr, int timeoutMillis); /*non-static for callbacks*/
Message next() {
    for (;;) {
            if (nextPollTimeoutMillis != 0) {
                Binder.flushPendingCommands();
            }

            nativePollOnce(ptr, nextPollTimeoutMillis);
    	...
}

最终调用到Looper类的pollInner函数中,调用 epoll_wait,会等待消息,直到有消息后,才会唤醒。阻塞是不会消耗CPU的时间片,不会导致CPU占用率高。总结来说,没有消息时,会一直阻塞在nativePollOnce函数里,此时主线程会释放CPU资源进入休眠状态,知道有消息时,管道写入数据,调用nativeWork方法唤醒,这里涉及到Linux pipe/epoll机制。

源码路径:frameworks\base\core\jni\android_os_MessageQueue.cpp

代码语言:javascript
复制
static void android_os_MessageQueue_nativePollOnce(JNIEnv* env, jobject obj,
        jlong ptr, jint timeoutMillis) {
    NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);
    nativeMessageQueue->pollOnce(env, obj, timeoutMillis);
}
void NativeMessageQueue::pollOnce(JNIEnv* env, jobject pollObj, int timeoutMillis) {
    mPollEnv = env;
    mPollObj = pollObj;
    mLooper->pollOnce(timeoutMillis);
    mPollObj = NULL;
    mPollEnv = NULL;

    if (mExceptionObj) {
        env->Throw(mExceptionObj);
        env->DeleteLocalRef(mExceptionObj);
        mExceptionObj = NULL;
    }
}

源码路径:system/core/libutils/Looper.cpp

代码语言:javascript
复制
int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) {
    int result = 0;
    for (;;) {
		...
        result = pollInner(timeoutMillis);
    }
}
int Looper::pollInner(int timeoutMillis) {
    ...
    struct epoll_event eventItems[EPOLL_MAX_EVENTS];
    //等待事件发生或者超时,在nativeWake()方法,向管道写端写入字符,则该方法会返回;
    int eventCount = epoll_wait(mEpollFd.get(), eventItems, EPOLL_MAX_EVENTS, timeoutMillis);
}

总结

Activity的启动过程。其中包含了根Activity(应用程序)启动过程和普通Activity的启动过程,进程之间的调用关系,同时补充了消息循环创建过程,拆解出两个面试常客进行了解析。根Activity启动过程中包含AMS向Zygote进程发送创建应用程序进程请求的逻辑。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 首语
  • Activity启动过程
    • 根Activity(应用程序)启动过程
      • 普通Activity的启动过程
        • 进程调用
        • 补充
          • 消息循环创建过程
            • 主线程 Looper.loop() 死循环为何不会ANR
            • Looper.loop()死循环为何不会导致CPU占用率过高
        • 总结
        相关产品与服务
        容器服务
        腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档