Activity启动过程

Activity启动流程概述 对于通过点击应用图标启动activity的场景说,AMS在这一步中没回调用startProcessLocked来创建一个新的进程,而对于通过在内部启动新的activity来说,这一步不需要执行,因为新的activity就在原来的activity所在的进程中启动。无论是通过Launcher启动,还是通过activity 内部来调用startActivity接口 来启动新的activity,都是通过Binder进程间通信进入到AMS进程中,并且调用AMS.startActivity 接口。 阅读详情

首语

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

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,它是当前应用程序进程的主线程,它处理ATMS的调度和Activity相关的操作。然后调用ActivityThread类的getInstrumentation方法,返回Instrumentation对象。

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

@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

public Instrumentation getInstrumentation(){
    return mInstrumentation;
}

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

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

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

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

	@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

    ActivityStarter obtainStarter(Intent intent, String reason) {
        return mFactory.obtain().setIntent(intent).setReason(reason);
    }

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

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

int execute() {
   try {
		...
        res = executeRequest(mRequest);
   }
}
private int executeRequest(Request request) {
    ...
    if (resultTo != null) {
        //ActivityRecord为Activity的描述类,记录Activity所有信息
        sourceRecord = ActivityRecord.isInAnyTask(resultTo);
    }
    //这里创建了ActivityRecord,记录了Activity所有信息
    final ActivityRecord r = new ActivityRecord.Builder(mService)
                .setCaller(callerApp)
                .setLaunchedFromPid(callingPid)
                .setLaunchedFromUid(callingUid)
                .setLaunchedFromPackage(callingPackage)
                .setLaunchedFromFeature(callingFeatureId)
                .setIntent(intent)
                .setResolvedType(resolvedType)
                .setActivityInfo(aInfo)
                .setConfiguration(mService.getGlobalConfiguration())
                .setResultTo(resultRecord)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setComponentSpecified(request.componentSpecified)
                .setRootVoiceInteraction(voiceSession != null)
                .setActivityOptions(checkedOptions)
                .setSourceRecord(sourceRecord)
                .build();
        mLastStartActivityRecord = r;
    ...    
    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

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

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

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

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方法中进行赋值的,那是谁调用了这个方法呢?

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

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

@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

@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

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

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

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

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

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

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

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

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

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

	@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。

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);
    			...
}
ClientLifecycleManager getLifecycleManager() {
        return mLifecycleManager;
    }

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

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

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,IApplicationThread接口定义了AMS可以访问App的接口,AMS通过这些接口控制App进程和完成App的响应。为了进程间通信对应的ApplicationThread需要继承它并实现相应的方法。ApplicationThread是ActivityThread的内部类,是ActivityThread于AMS通信的桥梁。

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

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

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

 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

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

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就被启动了。

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

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

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

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

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

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

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进程发送创建应用程序进程请求的逻辑。

Android Activity启动流程○ 从点击屏幕上的应用icon,到该应用展示第一个可视界面,这个过程中,Android系统究竟做了什么操作?又涉及到哪些进程? 1.根Activity启动过程 ①从Launcher到AMS 当点击屏幕上的应用icon时,Laucher发送启动应用的请求给AMS,因为Launcher是在Launcher进程,而AMS是在SystemServer进程。因此,实现这个请求,本质上是在实现一个跨进程通信的功能。在安卓领域实现跨进程通信的技术有多种,像是Broadcast、ContentProvinder等。在系. 阅读详情

相关推荐

Activity启动过程详解

1. 简介 本文源码基于android 27。 startActivity的流程较复杂,我们这里将其过程分成三部分: startActivity–>ActivityManagerService ActivityManagerService–>ApplicationThread ApplicationThread–>Activity 这样看起来稍微简单点。 通

四月葡萄的博客 2727

Activity 的启动流程(Android 13)

Activity 的启动过程分为两种:一种是普通 Activity 的启动过程,另一种是根 Activity 的启动过程。普通 Activity 指的是除应用程序启动的第一个 Activity 之外的其他 Activity。

xingyu19911016的博客 2万+

Android Activity的启动过程源码解析

所有的这一切都被系统封装好了,对我们来说是透明的,我们使用的时候仅仅是传递一个intent然后startActivity就可以达到目的了,不过,阅读了本文以后,你将会了解它的背后到底做了哪些事情。说明:我想再说一下这个方法checkStartActivityResult,它也专业抛异常的,看代码,相信大家对下面的异常信息不陌生吧,就是它干的,其中最熟悉的非Unable to find explicit activity class莫属了,如果你在xml中没有注册目标activity,此异常将会抛出。

huahaiyi的博客 1292

Android Activity启动过程详解

ctivity启动的流程分为两部分:一是在activity中通过startActivity(Intent intent)方法启动一个Activity;二是我们在桌面通过点击应用图标启动一个App然后显示Activity;第二种方式相较于第一种方式更加全面和复杂,所以本文会以第二种流程来分析。应用的启动流程大致分为下面五个阶段:1,应用启动进程 Launcher 调用 ATMS 系统进程的过程2,ATMS 向 AMS 发送创建应用进程的过程。

allen_xu_2012_new的博客 1万+

图解Activity启动流程

看一百遍不如做一遍,道理都懂,那么赶紧做出第一步吧!

Android小码家 3506

B站李沐讲论文笔记AlexNet

B站李沐讲论文笔记AlexNet

夏知识不进脑子薇的博客 789

Activity的启动过程

Android Activity的启动过程 前言 在了解Activity的启动的过程的时候,我们需要先了解下面几个东西是什么,这将更加有助于你深入了解android 活动的启动机制 老司机绕道 Activity 这个类大家再熟悉不过了,android最重要的组件之一,实际上它就是一个Java对象,它会被创建,同时也会被垃圾回收就只销毁,只不过它受AMS(ActivityManag

王者的心,青铜的手 249

LVGL开发新选择:深度对比NXP GUI Guider与SquareLine Studio,免费版够用吗?

本文深度对比了LVGL开发中两款主流工具NXP GUI Guider与SquareLine Studio的核心差异,包括功能定位、设计能力、代码生成质量和硬件适配等方面。针对不同项目需求,分析了免费版工具的适用性,帮助开发者根据预算和功能需求做出明智选择。特别关注了GUI设计工具在嵌入式开发中的实际应用效果。

weixin_26976635的博客 426

Activity 启动过程

这边会去掉关于启动进程 Launcher、孵化进程 Zygote 等有关的篇幅。进入主题吧当我们在面试的时候被问及,我们应该怎么回答呢?根 Activity 的启动流程普通 Activity 的启动流程,这边总结下。

hqb112233的博客 1757

MODBUS通讯不求人:手把手教你用三菱FX2N控制士林变频器

本文详细介绍了如何使用三菱FX2N PLC通过MODBUS协议控制士林变频器,涵盖硬件连接、参数配置、程序设计及通讯优化等关键步骤。特别针对没有内置MODBUS函数块的老款PLC,提供了CRC校验和稳定数据交换的实用解决方案,帮助工程师快速实现工业自动化设备的高效通讯。

v4w5x6的博客 226

海康威视摄像机SDK二次开发--提取音频保存至文件

由于最近在开发海康威视摄像头,特此记录一下如何提取音频数据,这里主要依靠语音对讲返回的音频数据,通过回调函数写入文件中,加个WAV头即可播放,编码格式可以自己设置在代码中有注释 文件结构 其中CameraInfo内容可以参看海康威视摄像机SDK二次开发–实时预览视频流保存到指定文件中 HIKSDKSaveRealData中的内容 package ClientDemo; import ClientDemo.CameraInfo; import com.sun.jna.NativeLong; import

RichardoMu的博客 3172

图解Activity的启动过程

由于Activity的启动涉及大量IPC和Binder方面的知识,因此了解这方面的知识后再来看Activity启动的相关源码可能不会那么吃力。

TellH的博客 6549

别再只调电压了!深入理解数控电源的CC/CV模式与双闭环PID控制(以BUCK电路为例)

本文深入解析数控电源的CC/CV模式与双闭环PID控制技术,以BUCK电路为例,探讨如何通过双闭环控制优化负载突变响应和模式切换稳定性。文章详细介绍了电压环与电流环的协同工作原理、PID参数整定技巧及工程实践中的非线性补偿方法,帮助工程师提升电源设计的智能控制能力。

weixin_27017211的博客 261

Android源码分析-Activity的启动过程

转载请注明出处:http://blog.youkuaiyun.com/singwhatiwanna/article/details/18154335前言Activity是Android中一个很重要的概念,堪称四大组件之首,关于Activity有很多内容,比如生命周期和启动Flags,这二者想要说清楚,恐怕又要写两篇长文,更何况分析它们的源码呢。不过本文的侧重点不是它们,我要介绍的是一个Activity典型的启

singwhatiwanna 4万+

第95节:多模型多卡推理管理

多模型推理:在同一硬件平台上同时部署多个不同或相同的深度学习模型,满足多任务需求。多卡推理:利用多块 GPU 资源,提升推理吞吐量与并发能力。目标:合理分配 GPU 资源,实现高效、低延迟的推理服务。

yumeiguo的博客 217

第4章--CANoe library开发 - 诊断功能

因为专栏要做的是汽车ECU自动化测试程序,测试的是ECU的诊断和刷新,因此就需要利用CANoe的接口,开发一些方便使用的诊断报文收发函数。

j187067046的博客 1397

Android Activity启动过程分析

当我们在一个Activity中(或通过Context对象),调用startActivity()方法来启动另一个Activity的工程中发发生了什么呢?这就是本文想跟大家分享的内容,我们一起通过源码的方式来看下Activity的启动过程(本文是基于Android Q源码)。  启动Activity的流程大体分为两步:找到要启动的Activity;然后启动它。(虽说有点像如何把大象装进冰箱,但也确实是那么回事,只不过每个步骤有更多细节) 找到Activity  要想启动一个Activity,系统先要找到这个.

sd_zhuzhipeng的专栏 3509

【AI大模型应用开发】1.0 Prompt Engineering(提示词工程)- 典型构成、原则与技巧,代码中加入Prompt

Prompt典型构成、原则与技巧,以及OpenAI API重要参数解释,助你轻松入门Prompt

同学小张的博客 2580

解析Activity的启动过程

Activity启动过程 Activity 的启动过程分为两种, 一种是根 Activity 的启动过程,另一种是普通Activity(子Activity)的启动过程。 根Activity:以快捷图标的形式显示在Launcher中,它的启动过程代表了一个Android应用程序的启动过程。 子Activity:由根Activity或其他子Activity启动,他们有可能与启动他们的Activity运行在同一个进程中,也可能运行在不同的进程中。 ...

lixiong0713的博客 2万+

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Activity组件启动过程分析

本文参考     1. Gityuan博文:startActivity启动过程分析     2. 老罗博文:Activity组件的启动过程 整理文档 网盘地址:https://pan.baidu.com/s/1hrEn2O8

wo_sxn的博客 884

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Activity的启动过程详解

文章目录 一、概述 二、流程分析 2.1 Activity启动的发起 2.2 Activity的管理——ATMS 2.3 线程切换及消息处理——mH 2.4 Activity启动核心实现——初始化及生命周期 三、根Activity的启动—应用进程启动 3.1 应用进程的创建 3.2 根Activity的启动 总结 一、概述 话说Android中有四大组件:Activity、Service、BroadcastReceiver、Cont.

Android 1791

安卓进阶八:Activity的启动过程

目录 一、Activity的分类 二、Activity的启动方式 三、根Activity的启动过程 四、子Activity的在根Activity相同进程中的启动过程 五、子Activity在新进程中的启动过程 一、Activity分类 Activity可分为根Activity和子Activity两种 根Activity是以快捷图标显示在Launcher中,它的启动过程就代表了一个应用程序的启动过程 子Activity由根Activity或...

我的安卓之路 437

Activity启动模式,启动过程

面试总结,关于Activity启动模式、启动过程,Intent匹配规则、App启动流程等

Huang兄 360

根Activity的启动过程

《安卓进阶解密》读书笔记 这里分析的源码基于android-8.0.0_r4. 「根Activity的启动过程」和「Activity的启动_5.0」笔记记录的,有大部分过程是一样的. 概述 根Activity启动过程中设计到的进程及其交互 时序图如下 这里将根Activity的启动划分为四部分 Launcher请求AMS过程 AMS判断根Activity所需的应用程序进程是否已经存在并启动,若不存在,则请求Zygote进程创建应用程序进程,详情查看《应用程序进程启动过程》的笔记。应用程序进程启动后.

Giagor的博客 1254
上一篇: Launcher启动过程
下一篇: 四大组件的工作过程
八归少年
八归少年 新星创作者: 操作系统技术领域 新星创作者: 操作系统技术领域
博客等级 码龄9年 9011粉丝 63原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

八归少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值