This problem in the interview once “novice network” encountered, but then only asked “Activity start process”, here on the entire “App start process” complete source code analysis, I hope to help you.

Source code analysis

1. The process of capturing click events isLauncher#onClick -> Launcher#onClickAppShortcut -> Launcher#startAppShortcutOrInfoActivity -> Launcher#startActivitySafely -> Activity#startActivityThe Launcher3 source code is as follows:

// https://github.com/amirzaidi/Launcher3/blob/f7951c32984036eef2f2130f21abded3ddf6160a/src/com/android/launcher3/Launcher. java#L2249
public void onClick(View v) {... Object tag = v.getTag();if (tag instanceofShortcutInfo) { onClickAppShortcut(v); }... }// https://github.com/amirzaidi/Launcher3/blob/f7951c32984036eef2f2130f21abded3ddf6160a/src/com/android/launcher3/Launcher. java#L2412
protected void onClickAppShortcut(final View v) {...// Start activities
    startAppShortcutOrInfoActivity(v);
}

// https://github.com/amirzaidi/Launcher3/blob/f7951c32984036eef2f2130f21abded3ddf6160a/src/com/android/launcher3/Launcher. java#L2462
private void startAppShortcutOrInfoActivity(View v) {
    ItemInfo item = (ItemInfo) v.getTag();
    Intent intent;// The application is parsed and saved by PackageManagerService according to androidmanifest.xml when installed
    if (item instanceof PromiseAppInfo) {
        PromiseAppInfo promiseAppInfo = (PromiseAppInfo) item;
        intent = promiseAppInfo.getMarketIntent();
    } else{ intent = item.getIntent(); }...booleansuccess = startActivitySafely(v, intent, item); . }// https://github.com/amirzaidi/Launcher3/blob/f7951c32984036eef2f2130f21abded3ddf6160a/src/com/android/launcher3/Launcher. java#L2689
public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {... intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); . startActivity(intent, optsBundle); . }Copy the code

2. Take API 27 source code as an example, saidAcitvity#startActivity, we click on the source code to find the call isActivity#startActivityForResult, which is calledInstrumentation#execStartActivityThe source code for this method is as follows:

/ / http://androidxref.com/8.1.0_r33/xref/frameworks/base/core/java/android/app/Activity.java#4800
public void startActivity(Intent intent, @Nullable Bundle options) {
    if(options ! =null) {
        startActivityForResult(intent, -1, options);
    } else {
        // Note we want to go through this call for compatibility with
        // applications that may have overridden the method.
        startActivityForResult(intent, -1); }}/ / http://androidxref.com/8.1.0_r33/xref/frameworks/base/core/java/android/app/Activity.java#4482
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
        @Nullable Bundle options) {... Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options); . }Copy the code

In 3.Instrumentation#execStartActivityWe can find it called inActivityManager#getService()#startActivity, itsActivityManager#getService()It takes a singleton and returns an implementationIActivityManagerThe type ofBinderObject, whose concrete implementation is inActivityManagerServiceIn the.

/ / http://androidxref.com/8.1.0_r33/xref/frameworks/base/core/java/android/app/Instrumentation.java#1578
public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {...try{...intresult = ActivityManager.getService() .startActivity(whoThread, who.getBasePackageName(), intent, intent.resolveTypeIfNeeded(who.getContentResolver()), token, target ! =null ? target.mEmbeddedID : null,
                    requestCode, 0.null, options); . }catch (RemoteException e) {
        ...
    }
    return null;
}

/ / http://androidxref.com/8.1.0_r33/xref/frameworks/base/core/java/android/app/ActivityManager.java#4216
public static IActivityManager getService(a) {
    return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
        new Singleton<IActivityManager>() {
            @Override
            protected IActivityManager create(a) {
                final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                final IActivityManager am = IActivityManager.Stub.asInterface(b);
                returnam; }};Copy the code

We’ll get there againActivityManagerService#startActivityLook at the source code and find that it is calledActivityManagerService#startActivityAsUserThe method is called againActivityStarter#startActivityMayWait, the source code is as follows:

// http://androidxref.com/8.1.0_r33/xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.ja va#4516
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
        Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
        int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
    return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
            resultWho, requestCode, startFlags, profilerInfo, bOptions,
            UserHandle.getCallingUserId());
}

@Override
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
        Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
        int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
    enforceNotIsolatedCaller("startActivity");
    userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
            userId, false, ALLOW_FULL_ONLY, "startActivity".null);
    // TODO: Switch to user app stacks here.
    return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
            resolvedType, null.null, resultTo, resultWho, requestCode, startFlags,
            profilerInfo, null.null, bOptions, false, userId, null."startActivityAsUser");
}
Copy the code

5. We found itActivityStarter#startActivityMayWait, which is calledActivityStarter#startActivityLockedAnd then theActivityStarter#startActivity, and then theActivityStarter#startActivityUnchecked, which is calledActivityStackSupervisor#resumeFocusedStackTopActivityLocked, the source code is as follows:

// http://androidxref.com/8.1.0_r33/xref/frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java#673
final int startActivityMayWait(IApplicationThread caller, int callingUid,
        String callingPackage, Intent intent, String resolvedType,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        IBinder resultTo, String resultWho, int requestCode, int startFlags,
        ProfilerInfo profilerInfo, WaitResult outResult,
        Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId,
        TaskRecord inTask, String reason) {...intres = startActivityLocked(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason); . }// http://androidxref.com/8.1.0_r33/xref/frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java#263
int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
        String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
        String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
        ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
        ActivityRecord[] outActivity, TaskRecord inTask, String reason) {... mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord, inTask); }// http://androidxref.com/8.1.0_r33/xref/frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java#294
private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
        String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
        String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
        ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
        ActivityRecord[] outActivity, TaskRecord inTask) {...return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
            options, inTask, outActivity);
}

// http://androidxref.com/8.1.0_r33/xref/frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java#988
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
        ActivityRecord[] outActivity) {... result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags, doResume, options, inTask, outActivity); . }// http://androidxref.com/8.1.0_r33/xref/frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java#1015
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
        ActivityRecord[] outActivity) {... mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity, mOptions); . }Copy the code

To 6.ActivityStackSupervisor#resumeFocusedStackTopActivityLockedIt was found that it was calledActivityStack#resumeTopActivityUncheckedLocked, and then theActivityStack#resumeTopActivityInnerLockedAnd then change back toActivityStackSupervisor.javaAnd call theActivityStackSupervisor#startSpecificActivityLockedIf yes, notify the process to start the Activity. Otherwise, create the process first.

// http://androidxref.com/8.1.0_r33/xref/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.j ava#2085
boolean resumeFocusedStackTopActivityLocked( ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {...returntargetStack.resumeTopActivityUncheckedLocked(target, targetOptions); . }// http://androidxref.com/8.1.0_r33/xref/frameworks/base/services/core/java/com/android/server/am/ActivityStack.java#2245
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {... result = resumeTopActivityInnerLocked(prev, options); . } http:/ / androidxref.com/8.1.0_r33/xref/frameworks/base/services/core/java/com/android/server/am/ActivityStack.java#2286
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {... mStackSupervisor.startSpecificActivityLocked(next,true.true); . }// http://androidxref.com/8.1.0_r33/xref/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.j ava#1560
void startSpecificActivityLocked(ActivityRecord r,
        boolean andResume, boolean checkConfig) {...if(app ! =null&& app.thread ! =null) {...// If the process already exists, notify the process to start the component
        realStartActivityLocked(r, app, andResume, checkConfig);
        return; . }// Otherwise, create the process first
    mService.startProcessLocked(r.processName, r.info.applicationInfo, true.0."activity", r.intent.getComponent(), false.false.true); . }Copy the code

7. We analyze situations where the process does not yet exist because we will encounter them again laterActivityStackSupervisor#realStartActivityLocked.ActivityStackSupervisor#startSpecificActivityLockedUsed by the process created inmServiceActivityManagerService, we look atActivityManagerService#startProcessLockedThe source code is as follows:

// http://androidxref.com/8.1.0_r33/xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.ja va#3777
private final void startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {...if (entryPoint == null) entryPoint = "android.app.ActivityThread"; startResult = Process.start(entryPoint, app.processName, uid, uid, gids, debugFlags, mountExternal, app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, app.info.dataDir, invokeWith, entryPointArgs); . }Copy the code

8. Discover the final callProcess#startTo start the process, the process entry is inandroid.app.ActivityThread.javaIn the classmain()Delta function, so we’re going to go fromActivityThread#mainTo analyze, it callsActivityThread#attach, includingActivityManager.getService()As mentioned earlier, what you get back is an implementationIActivityManagerThe type ofBinderObject, whose concrete implementation is inActivityManagerService, the relevant source code is as follows:

/ / http://androidxref.com/8.1.0_r33/xref/frameworks/base/core/java/android/app/ActivityThread.java#6459
public static void main(String[] args) {... Looper.prepareMainLooper(); ActivityThread thread =new ActivityThread();
    thread.attach(false); . Looper.loop(); . }/ / http://androidxref.com/8.1.0_r33/xref/frameworks/base/core/java/android/app/ActivityThread.java#6315
private void attach(boolean system) {
    sCurrentActivityThread = this;
    mSystemThread = system;
    if(! system) { ...final IActivityManager mgr = ActivityManager.getService();
        try {
            mgr.attachApplication(mAppThread);
        } catch(RemoteException ex) { ... }... }... }Copy the code

9. We’re backActivityManagerServiceTo view itattachApplicationFunction, found calledthread#bindApplicationmStackSupervisor#attachApplicationLockedWe explain what each method does in turn, and the source code looks like this:

// http://androidxref.com/8.1.0_r33/xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.ja va#7215
public final void attachApplication(IApplicationThread thread) {... attachApplicationLocked(thread, callingPid); . }// http://androidxref.com/8.1.0_r33/xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.ja va#6911
private final boolean attachApplicationLocked(IApplicationThread thread,
        int pid) {... thread.bindApplication(processName, appInfo, providers, app.instr.mClass, profilerInfo, app.instr.mArguments, app.instr.mWatcher, app.instr.mUiAutomationConnection, testMode, mBinderTransactionTrackingEnabled, enableTrackAllocation, isRestrictedBackupMode || ! normalMode, app.persistent,newConfiguration(getGlobalConfiguration()), app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked(), buildSerial); .if (normalMode) {
        try {
            if (mStackSupervisor.attachApplicationLocked(app)) {
                didSomething = true; }}catch(Exception e) { ... }}... }Copy the code

10. It says sothread#bindApplicationIn thisthreadComes from theActivityThread#mAppThread, its type isApplicationThread, it isActivityThreadAn inner class inherited fromIApplicationThread.StubLet’s check it outApplicationThread#bindApplicationFound that the last callActivityThread#sendMessageMethod, it calls internallymH.sendMessageTo send a message,mHActivityThreadThe inner classHFor an example ofH#handleMessageTo see what it does with the messages that come in, and it gets thereActivityThread#handleBindApplication.

The Application object is created by calling data#info#makeApplication. The data#info object is an instance of LoadedApk, Instrumentation#newApplication Instrumentation#newApplication, Instrumentation#newApplication, Class#newInstance() Instrumentation#newApplication Then call Application#attach(context) to bind the context.

Instrumentation#callApplicationOnCreate Instrumentation#callApplicationOnCreate Instrumentation#callApplicationOnCreate Instrumentation#callApplicationOnCreate

/ / http://androidxref.com/8.1.0_r33/xref/frameworks/base/core/java/android/app/ActivityThread.java#899
public final void bindApplication(String processName, ApplicationInfo appInfo,
        List<ProviderInfo> providers, ComponentName instrumentationName,
        ProfilerInfo profilerInfo, Bundle instrumentationArgs,
        IInstrumentationWatcher instrumentationWatcher,
        IUiAutomationConnection instrumentationUiConnection, int debugMode,
        boolean enableBinderTracking, boolean trackAllocation,
        boolean isRestrictedBackupMode, boolean persistent, Configuration config,
        CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
        String buildSerial) {... sendMessage(H.BIND_APPLICATION, data); }/ / http://androidxref.com/8.1.0_r33/xref/frameworks/base/core/java/android/app/ActivityThread.java#2593
private void sendMessage(int what, Object obj) {
    sendMessage(what, obj, 0.0.false);
}

private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
    if (DEBUG_MESSAGES) Slog.v(
        TAG, "SCHEDULE " + what + "" + mH.codeToString(what)
        + ":" + arg1 + "/" + obj);
    Message msg = Message.obtain();
    msg.what = what;
    msg.obj = obj;
    msg.arg1 = arg1;
    msg.arg2 = arg2;
    if (async) {
        msg.setAsynchronous(true);
    }
    mH.sendMessage(msg);
}

/ / http://androidxref.com/8.1.0_r33/xref/frameworks/base/core/java/android/app/ActivityThread.java#1580
public void handleMessage(Message msg) {...switch (msg.what) {
        ...
        case BIND_APPLICATION:
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
            AppBindData data = (AppBindData)msg.obj;
            handleBindApplication(data);
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            break; . }}/ / http://androidxref.com/8.1.0_r33/xref/frameworks/base/core/java/android/app/ActivityThread.java#5429
private void handleBindApplication(AppBindData data) {...finalInstrumentationInfo ii; .// Create the mInstrumentation instance
    if(ii ! =null) {
        final ApplicationInfo instrApp = new ApplicationInfo();
        ii.copyTo(instrApp);
        instrApp.initForUser(UserHandle.myUserId());
        final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
                appContext.getClassLoader(), false.true.false);
        final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);

        try {
            final ClassLoader cl = instrContext.getClassLoader();
            mInstrumentation = (Instrumentation)
                cl.loadClass(data.instrumentationName.getClassName()).newInstance();
        } catch(Exception e) { ... }... }else {
        mInstrumentation = newInstrumentation(); }... Application app; .// Create Application instance
    try{... app = data.info.makeApplication(data.restrictedBackupMode,null); mInitialApplication = app; .try {
            mInstrumentation.callApplicationOnCreate(app);
        } catch(Exception e) { ... }}finally{... }... }/ / http://androidxref.com/8.1.0_r33/xref/frameworks/base/core/java/android/app/LoadedApk.java#959
public Application makeApplication(boolean forceDefaultAppClass,
        Instrumentation instrumentation) {
    Application app = null;

    String appClass = mApplicationInfo.className;
    if (forceDefaultAppClass || (appClass == null)) {
        appClass = "android.app.Application";
    }

    try{ java.lang.ClassLoader cl = getClassLoader(); . ContextImpl appContext = ContextImpl.createAppContext(mActivityThread,this);
        app = mActivityThread.mInstrumentation.newApplication(
                cl, appClass, appContext);
        appContext.setOuterContext(app);
    } catch (Exception e) {
        ...
    }
    mActivityThread.mAllApplications.add(app);
    mApplication = app;

    if(instrumentation ! =null) {// The input is null, so no walk
        try {
            instrumentation.callApplicationOnCreate(app);
        } catch(Exception e) { ... }}...return app;
}

/ / http://androidxref.com/8.1.0_r33/xref/frameworks/base/core/java/android/app/Instrumentation.java#1084
public Application newApplication(ClassLoader cl, String className, Context context)
        throws InstantiationException, IllegalAccessException,
        ClassNotFoundException {
    return newApplication(cl.loadClass(className), context);
}

static public Application newApplication(Class
        clazz, Context context)
        throws InstantiationException, IllegalAccessException,
        ClassNotFoundException {
    Application app = (Application)clazz.newInstance();
    app.attach(context);
    return app;
}
Copy the code

11. That’s all for 9thread#bindApplicationLet’s move onmStackSupervisor#attachApplicationLocked, itsmStackSupervisorActivityStackSupervisorAn example of what we are looking atActivityStackSupervisor#attachApplicationLockedMethod is found to be calledActivityStackSupervisor#realStartActivityLocked, whose method is calledapp#thread#scheduleLaunchActivity, the source code is as follows:

// http://androidxref.com/8.1.0_r33/xref/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.j ava#956
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
    finalString processName = app.processName; .if (realStartActivityLocked(activity, app,
            top == activity /* andResume */.true /* checkConfig */)) {... }... }// http://androidxref.com/8.1.0_r33/xref/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.j ava#1313
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
        boolean andResume, boolean checkConfig) throws RemoteException {... app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
            System.identityHashCode(r), r.info,
            // TODO: Have this take the merged configuration instead of separate global
            // and override configs.mergedConfiguration.getGlobalConfiguration(), mergedConfiguration.getOverrideConfiguration(), r.compat, r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results, newIntents, ! andResume, mService.isNextTransitionForward(), profilerInfo); . }Copy the code

12. As mentioned aboveapp#thread#scheduleLaunchActivityIn thethreadThat was mentioned earlierIApplicationThread, its implementation class isActivityThread#ApplicationThread, we look atActivityThread#ApplicationThread#scheduleLaunchActivityThe code found in is ultimately sentLAUNCH_ACTIVITYMessage, which we have analyzed in step 10, we can directly look at the message processing code, in theH#handleMessageIn, we can see that it receives and processes many operations related to the four componentsLAUNCH_ACTIVITYIt is found that the method of its processing isActivityThread#handleLaunchActivityAnd it callsActivityThread#performLaunchActivityMethod, the implementation of which is covered againInstrumentationClass, which was created beforeApplicationObject uses it, now createActivityObject uses it again, itsInstrumentation#newActivitythroughClass.newInstance()To instantiateActivity, returns after the instantiationActivityThread#performLaunchActivityTo get inactivityAttach to the window, and thencallActivityOnCreateActivityonCreateThe source code involved in the lifecycle is as follows:

/ / http://androidxref.com/8.1.0_r33/xref/frameworks/base/core/java/android/app/ActivityThread.java#756
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
        ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
        CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
        int procState, Bundle state, PersistableBundle persistentState,
        List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
        boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {... sendMessage(H.LAUNCH_ACTIVITY, r); }/ / http://androidxref.com/8.1.0_r33/xref/frameworks/base/core/java/android/app/ActivityThread.java#1580
public void handleMessage(Message msg) {...switch (msg.what) {
        ...
        case LAUNCH_ACTIVITY: {
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
            final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

            r.packageInfo = getPackageInfoNoCheck(
                    r.activityInfo.applicationInfo, r.compatInfo);
            handleLaunchActivity(r, null."LAUNCH_ACTIVITY");
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        } break; . }}/ / http://androidxref.com/8.1.0_r33/xref/frameworks/base/core/java/android/app/ActivityThread.java#2833
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {... Activity a = performLaunchActivity(r, customIntent); . }/ / http://androidxref.com/8.1.0_r33/xref/frameworks/base/core/java/android/app/ActivityThread.java#2644
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {... Activity activity =null;
    try{ java.lang.ClassLoader cl = appContext.getClassLoader(); activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent); . }catch (Exception e) {
        ...
    }

    try {
        // Return the previously created Application object
        Application app = r.packageInfo.makeApplication(false, mInstrumentation); .if(activity ! =null) {...// attach to the window
            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.configCallback); .if (r.isPersistable()) {
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
            } else{ mInstrumentation.callActivityOnCreate(activity, r.state); }... }}catch (Exception e) {
        ...
    }
    return activity;
}

/ / http://androidxref.com/8.1.0_r33/xref/frameworks/base/core/java/android/app/Instrumentation.java#1143
public Activity newActivity(ClassLoader cl, String className, Intent intent)
        throws InstantiationException, IllegalAccessException,
        ClassNotFoundException {
    return (Activity)cl.loadClass(className).newInstance();
}

public Activity newActivity(Class
        clazz, Context context, IBinder token, Application application, Intent intent, ActivityInfo info, CharSequence title, Activity parent, String id, Object lastNonConfigurationInstance) throws InstantiationException,
        IllegalAccessException {
    Activity activity = (Activity)clazz.newInstance();
    ActivityThread aThread = null;
    activity.attach(context, aThread, this, token, 0 /* ident */, application, intent,
            info, title, parent, id,
            (Activity.NonConfigurationInstances)lastNonConfigurationInstance,
            new Configuration(), null /* referrer */.null /* voiceInteractor */.null /* window */.null /* activityConfigCallback */);
    return activity;
}
Copy the code

So far, the startup process of an App has been analyzed. Finally, the flow chart of the classes involved in the startup is presented:

conclusion

I am creating an interview library to help Android developers get better offers ———— Android Offer Harvest base, welcome star, feel good can continue to follow, interested can join me to build together.