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

【C语言项目合集】这十个入门必备练手项目,让C语言对你来说不再难学!

适合刚入门C语言的编程学习小白的十个练手项目,每个都很经典且实用,让你学完C语言不再迷茫!

kxtxdy的博客 3万+

Activity的启动过程

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

王者的心,青铜的手 249

NVIDIA DGX Spark 深度应用解析:从大模型训练到边缘推理的完整实践指南

内存管理:充分利用统一内存架构,避免不必要的数据传输批处理大小:根据模型大小调整批处理大小以优化内存使用精度选择:在精度损失可接受范围内使用较低精度计算流水线优化:重叠计算和数据传输操作DGX Spark作为一个专门的AI计算平台,在大模型开发的各个阶段都能发挥重要作用。从数据预处理到模型训练,从微调到推理部署,其统一内存架构和强大的计算能力为AI开发者提供了前所未有的本地开发体验。需要注意的是,虽然DGX Spark性能强大,但合理的算法设计和系统优化仍然是获得最佳性能的关键。

time_days的博客 2869

Activity 启动过程

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

hqb112233的博客 1757

10X Genomics数据实战:手把手教你用Seurat处理单细胞PBMC数据(附完整代码)

本文详细介绍了如何使用Seurat处理10X Genomics的单细胞PBMC数据,从数据获取、质控到降维分析和细胞分群的全流程。通过实战代码演示,帮助研究者掌握单细胞RNA测序数据分析的核心技术,提升对细胞异质性的理解。

weixin_29053577的博客 252

STM32 RTC_WaitForSynchro()死循环问题分析与LSI时钟优化实践

本文深入分析了STM32使用LSI时钟源时,调用RTC_WaitForSynchro()函数陷入死循环的根本原因。问题核心在于RTC时钟域未正确使能,导致硬件同步标志RSF无法置位。文章提供了通过显式调用RCC_RTCCLKCmd(ENABLE)函数启用RTC时钟总开关的解决方案,并分享了编写健壮RTC/BKP初始化代码、增加超时机制等最佳实践,确保系统稳定运行。

weixin_29185493的博客 510

图解Activity的启动过程

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

TellH的博客 6549

01|无代码开发 | 如何使用Zion实现导航网站制作

以上就是我制作导航网站的心得,分享给大家,作为一个小白想要独立搭建一个网站还是比较困难的,而在Zion不仅可以用可视化的方法进行搭建,甚至还可以一键发布,不用考虑服务器域名啥的问题,真是太方便了。

2301_76262110的博客 1390

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

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

singwhatiwanna 4万+

用STM32的SPI模式2搞定SSI绝对值编码器通信(附完整代码与避坑点)

本文详细解析了如何使用STM32的SPI模式2实现SSI绝对值编码器通信,包括硬件设计、SPI配置、数据处理算法及稳定性优化技巧。通过完整的代码示例和避坑指南,帮助工程师解决时序匹配、数据解析等常见问题,提升工业自动化系统中的编码器通信可靠性。

weixin_27252001的博客 264

【CATIA的二次开发38】对象Selection交互选择部分方法介绍01

在CATIA V5的VBA开发中,Selection对象是用户交互的核心组件,用于管理用户在图形区域或特征树中的选择操作。Selection 对象是 CATIA VBA 中的中央交互枢纽,充当用户界面与程序逻辑之间的桥梁。它代表当前在图形区域或特征树中被选中的元素集合,是自动化操作的基础。

学习共勉:不积跬步,无以至千里; 不积小流,无以成江海。 1337

Android Activity启动过程分析

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

sd_zhuzhipeng的专栏 3509

MOSFET导通电阻Rdson全解析:物理组成、公式推导与工程选型要点

在功率电子设计中,MOSFET作为核心开关器件,其导通电阻Rdson直接决定导通损耗与系统效率。从半导体物理角度看,Rdson并非单一固定值,而是由源极电阻、沟道电阻、累积层电阻、JFET区电阻、漂移区电阻及衬底电阻等多个分量串联而成,并随栅极驱动电压、结温以及击穿电压等级发生显著变化。理解Rdson的物理来源与数学表达,有助于工程师在低压大电流与高压小电流等不同场景中合理选型、优化驱动电压并准确估算热损耗。文章从沟道电阻公式出发,深入剖析耐压与导通电阻的物理矛盾、温度系数的影响规律,并给出数据手册参数的正

weixin_29163857的博客 191

解析Activity的启动过程

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

lixiong0713的博客 2万+

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Activity组件启动过程分析

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

wo_sxn的博客 884

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

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

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

安卓进阶八: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、付费专栏及课程。

余额充值