1. 程式人生 > >Android應用程式啟動詳解(二)從原始碼瞭解App的啟動過程

Android應用程式啟動詳解(二)從原始碼瞭解App的啟動過程

本文承接《Android應用程式啟動詳解(一)》繼續來學習應用程式的啟動的那些事。上文提到startActivity()方法啟動一個app後經過一翻過程就到了app的入口方法ActivityThread.main()。其實我們在之前的文章中《Android的訊息機制(二)之Looper的使用》介紹主執行緒為何可接收訊息時也簡單提到過此入口方法。關於主執行緒可接收訊息的原因是因為在ActivityThread.main()中為主執行緒建立了Looper。現在我們繼續來再看看ActivityThread.main()方法的原始碼:

Application的啟動過程

ActivityThread.java

public static void main(String[] args) {
    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
    SamplingProfilerIntegration.start();

    CloseGuard.setEnabled(false);

    Environment.initForCurrentUser();

    // Set the reporter for event logging in libcore
    EventLogger.setReporter(new EventLoggingReporter());

    // Make sure TrustedCertificateStore looks in the right place for CA certificates
    final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
    TrustedCertificateStore.setDefaultUserDirectory(configDir);

    Process.setArgV0("<pre-initialized>");

    // 建立Looper
    Looper.prepareMainLooper();

    // 關鍵程式碼:ActivityThread初始化,並呼叫attach()方法
    ActivityThread thread = new ActivityThread();
    thread.attach(false);

    if (sMainThreadHandler == null) {
        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.loop();

    throw new RuntimeException("Main thread loop unexpectedly exited");
}

可以看到,main()方法是一個靜態方法,ActivityThread物件在方法裡做了初始化,並呼叫了attach方法。我們繼續看下attach方法的原始碼:

final ApplicationThread mAppThread = new ApplicationThread();
……
private void attach(boolean system) {

    sCurrentActivityThread = this;

    mSystemThread = system;
    // 非系統app
    if (!system) {
        ViewRootImpl.addFirstDrawHandler(new Runnable() {
            @Override
            public void run() {
                ensureJitEnabled();
            }
        });

        android.ddm.DdmHandleAppName.setAppName("<pre-initialized>", UserHandle.myUserId());

        RuntimeInit.setApplicationObject(mAppThread.asBinder());
        // 關鍵程式碼1:獲得一個IActivityManager物件
        final IActivityManager mgr = ActivityManagerNative.getDefault();

        try {
            // 關鍵程式碼2:呼叫IActivityManager物件的attachApplication方法
            mgr.attachApplication(mAppThread);

        } catch (RemoteException ex) {

            throw ex.rethrowFromSystemServer();

        }
        ……
    } else {
        // 系統app……
    }
    ……
}

attach方法接收一個引數:system,用於區分是否系統app,這裡我們傳入的是false,所以我們只看非系統app的判斷分支程式碼,這裡有兩行關鍵程式碼:

邏輯意思是通過ActivityManagerNative的getDefault()方法獲得一個IActivityManager物件,在前面《Android應用程式啟動詳解(一)》我們已經瞭解到此物件就是ActivityManagerService。所以程式碼:mgr.attachApplication(mAppThread);中attachApplication方法實體便在ActivityManagerService中,引數是ApplicationThread物件,看程式碼:

ActivityManagerService.java

@Override
public final void attachApplication(IApplicationThread thread) {

    synchronized (this) {

        int callingPid = Binder.getCallingPid();

        final long origId = Binder.clearCallingIdentity();
        // 關鍵程式碼
        attachApplicationLocked(thread, callingPid);
        Binder.restoreCallingIdentity(origId);
    }
}
private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {

        ……
        ProfilerInfo profilerInfo = profileFile == null ? null : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
        // 關鍵程式碼1
        thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,

                profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
                app.instrumentationUiAutomationConnection, testMode,
                mBinderTransactionTrackingEnabled, enableTrackAllocation,
                isRestrictedBackupMode || !normalMode, app.persistent,
                new Configuration(mConfiguration), app.compat,
                getCommonServicesLocked(app.isolated),
                mCoreSettingsObserver.getCoreSettingsLocked());
        updateLruProcessLocked(app, false, null);
        app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
    } catch (Exception e) {
        ……
    }
     ……
       if (normalMode) {
        try {
            // 關鍵程式碼2 去啟動Activity
            if (mStackSupervisor.attachApplicationLocked(app)) {
                didSomething = true;
            }
        } catch (Exception e) {
            Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
            badApp = true;
        }
    }
    ……
    return true;
}

attachApplication方法中呼叫了另外一個關鍵的方法:attachApplicationLocked。attachApplicationLocked方法細節夠多,我們只看關鍵部分,請先記住關鍵程式碼2,這是Application啟動成功後,Activity的啟動關鍵過程,我們後面來分析,現在請看關鍵程式碼1這行,我們前面知道,thread是ActivityThread中的ApplicationThread物件,這裡thread也是繼承了IBinder,這裡也進行了跨程序程序間通訊,所以又回到ActivityThread中檢視程式碼:

ActivityThread.java

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<String, IBinder> services, Bundle coreSettings) {

    if (services != null) {
        // Setup the service cache in the ServiceManager
        ServiceManager.initServiceCache(services);
    }

    setCoreSettings(coreSettings);

    AppBindData data = new AppBindData();
    data.processName = processName;
    data.appInfo = appInfo;
    data.providers = providers;
    data.instrumentationName = instrumentationName;
    data.instrumentationArgs = instrumentationArgs;
    data.instrumentationWatcher = instrumentationWatcher;
    data.instrumentationUiAutomationConnection = instrumentationUiConnection;
    data.debugMode = debugMode;
    data.enableBinderTracking = enableBinderTracking;
    data.trackAllocation = trackAllocation;
    data.restrictedBackupMode = isRestrictedBackupMode;
    data.persistent = persistent;
    data.config = config;
    data.compatInfo = compatInfo;
    data.initProfilerInfo = profilerInfo;
    sendMessage(H.BIND_APPLICATION, data);
}

此處看得到,是發了一個BIND_APPLICATION訊息,繼續看看訊息接收地方做了啥事情:

public void handleMessage(Message msg) {
    if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
    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;
            }
            ……
    Object obj = msg.obj;
    if (obj instanceof SomeArgs) {
        ((SomeArgs) obj).recycle();
    }
    if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
}

這裡關鍵程式碼是handleBindApplication方法,繼續向下看原始碼:

private void handleBindApplication(AppBindData data) {
    ……
    final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
    try {
        // 關鍵程式碼1
        Application app = data.info.makeApplication(data.restrictedBackupMode, null);
        mInitialApplication = app;

        if (!data.restrictedBackupMode) {
            if (!ArrayUtils.isEmpty(data.providers)) {
                installContentProviders(app, data.providers);
                mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
            }
        }

        try {
            mInstrumentation.onCreate(data.instrumentationArgs);

        }
        catch (Exception e) {
            throw new RuntimeException( "Exception thrown in onCreate() of "
                + data.instrumentationName + ": " + e.toString(), e);
        }

        try {
            // 關鍵程式碼2
            mInstrumentation.callApplicationOnCreate(app);
        } catch (Exception e) {
            if (!mInstrumentation.onException(app, e)) {
                throw new RuntimeException(
                    "Unable to create application " + app.getClass().getName()
                    + ": " + e.toString(), e);
            }
        }
    } finally {
        StrictMode.setThreadPolicy(savedPolicy);
    }
}

這也是一個夠長的方法,我們還是隻看關鍵程式碼行:關鍵程式碼1中data.info是一個LoadedApk類物件,它返回一了一個Application物件,並賦予全域性變數mInitialApplication。到此你一定猜測些Application物件是不是就是我們app中常用的Application物件?答案是:你猜對了。再來看關鍵程式碼2,在創建出Application物件後,呼叫了callApplicationOnCreate(app)方法:

Instrumentation.java

public void callApplicationOnCreate(Application app) {
    app.onCreate();
}

這就是我們繼承Application類的onCreate()方法了。看到這裡應該會有點小興奮吧,因為我們終於知道了Application的onCreate()方法被回撥的原理了。事情還沒完,讓我們繼續刨根問底,看看Application是如何創建出來的,看回handleBindApplication()方法的關鍵程式碼1呼叫的makeApplication()方法,它的原始碼:

LoadedApk.java

public Application makeApplication(boolean forceDefaultAppClass,

        Instrumentation instrumentation) {

    if (mApplication != null) {
        return mApplication;
    }

    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");
    Application app = null;
    String appClass = mApplicationInfo.className;
    if (forceDefaultAppClass || (appClass == null)) {
        appClass = "android.app.Application";
    }

    try {
        java.lang.ClassLoader cl = getClassLoader();
        if (!mPackageName.equals("android")) {
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "initializeJavaContextClassLoader");
            initializeJavaContextClassLoader();
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        }
        ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
        // 關鍵程式碼
        app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);
        appContext.setOuterContext(app);
    } catch (Exception e) {
        if (!mActivityThread.mInstrumentation.onException(app, e)) {
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            throw new RuntimeException(
                "Unable to instantiate application " + appClass
                + ": " + e.toString(), e);
        }
    }

    mActivityThread.mAllApplications.add(app);
    mApplication = app;
    ……
    return app;
}

請看關鍵程式碼行,方法引數傳入了繼承Application的類的類名appClass,再看原始碼:

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

上面程式碼很簡單了,在建立Application後,就呼叫了attach方法:

Application.java

final void attach(Context context) {
    attachBaseContext(context);
    mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}

ContextWrapper.java

protected void attachBaseContext(Context base) {
    if (mBase != null) {
        throw new IllegalStateException("Base context already set");
    }
    mBase = base;
}

能看出,在Application建立後,第一個呼叫的是attachBaseContext()方法,然後再是onCreate()方法。

Activity的啟動過程

回到上面提到的ActivityManagerService.java中的attachApplicationLocked()方法關鍵程式碼2處(紅色醒目文字提到先記住後面分析處),Application啟動成功後,下一步就是要啟動Activity了,請再看attachApplicationLocked()方法:

ActivityManagerService.java

private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {
        ……
        ProfilerInfo profilerInfo = profileFile == null ? null : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
        // 關鍵程式碼1
        thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
                profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
                app.instrumentationUiAutomationConnection, testMode,
                mBinderTransactionTrackingEnabled, enableTrackAllocation,
                isRestrictedBackupMode || !normalMode, app.persistent,
                new Configuration(mConfiguration), app.compat,
                getCommonServicesLocked(app.isolated),
                mCoreSettingsObserver.getCoreSettingsLocked());
        updateLruProcessLocked(app, false, null);
        app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
    } catch (Exception e) {
        ……
    }
     ……
       if (normalMode) {
        try {
            // 關鍵程式碼2 去啟動Activity
            if (mStackSupervisor.attachApplicationLocked(app)) {
                didSomething = true;
            }
        } catch (Exception e) {
            Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
            badApp = true;
        }
    }
    ……
    return true;
}

這次我們來看關鍵程式碼2,mStackSupervisor變數是一個ActivityStackSupervisor型別,這個類也是非常重要的,它決定著我們app是否能啟動成功,我們看看做了什麼:

ActivityStackSupervisor.java

boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {

    final String processName = app.processName;
    boolean didSomething = false;
    for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {

               // 關鍵程式碼1:當前應用的整個activity堆疊資訊
               ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
            final ActivityStack stack = stacks.get(stackNdx);
            if (!isFrontStack(stack)) {
                continue;
            }
            ActivityRecord hr = stack.topRunningActivityLocked(null);
            if (hr != null) {
                if (hr.app == null && app.uid == hr.info.applicationInfo.uid
                        && processName.equals(hr.processName)) {
                    try {
                        // 關鍵程式碼2:啟動Activity
                        if (realStartActivityLocked(hr, app, true, true)) {
                            didSomething = true;
                        }
                    } catch (RemoteException e) {
                        Slog.w(TAG, "Exception in new application when starting activity "
                              + hr.intent.getComponent().flattenToShortString(), e);
                        throw e;
                    }
                }
            }
        }
    }
    if (!didSomething) {
        ensureActivitiesVisibleLocked(null, 0);
    }
    return didSomething;
}

關鍵程式碼1處就是獲得Activity的堆疊資訊,我們繼續看關鍵程式碼2 呼叫了realStartActivityLocked()方法,這方法也是之前《Android應用程式啟動詳解(一)》中“從startActivity()到ActivityThread.main()流程原始碼分析”提到要先記住,這是也是從應用中啟動Activity所呼叫的方法,請看原始碼:

final boolean realStartActivityLocked(ActivityRecord r,
        ProcessRecord app, boolean andResume, boolean checkConfig)
        throws RemoteException {
        ……
        app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
        // 關鍵程式碼
        app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
                r.compat, r.launchedFromPackage, r.task.voiceInteractor, app.repProcState,
                r.icicle, r.persistentState, results, newIntents, !andResume,
                mService.isNextTransitionForward(), profilerInfo);
        ……
    return true;
}

請看關鍵程式碼,其中app是上一層傳過來的ActivityRecord,它代表的就是要開啟的Activity物件裡面分裝了很多資訊,比如所在的ActivityTask等,如果這是首次開啟應用,那麼這個Activity會被放到ActivityTask的棧頂,那麼app.thread這個IApplicationThread物件,這個就是我們的ApplicationThread,所以scheduleLaunchActivity()方法是:

ActivityThread.java

private class ApplicationThread extends ApplicationThreadNative {

    public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
            ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
            String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state,
            PersistableBundle persistentState, List<ResultInfo> pendingResults,
            List<ReferrerIntent> pendingNewIntents, boolean notResumed, boolean isForward,
            ProfilerInfo profilerInfo) {

        updateProcessState(procState, false);
        ActivityClientRecord r = new ActivityClientRecord();
        r.token = token;
        r.ident = ident;
        r.intent = intent;
        r.referrer = referrer;
        r.voiceInteractor = voiceInteractor;
        r.activityInfo = info;
        r.compatInfo = compatInfo;
        r.state = state;
        r.persistentState = persistentState;
        r.pendingResults = pendingResults;
        r.pendingIntents = pendingNewIntents;
        r.startsNotResumed = notResumed;
        r.isForward = isForward;
        r.profilerInfo = profilerInfo;
        updatePendingConfiguration(curConfig);
        sendMessage(H.LAUNCH_ACTIVITY, r);
    }
}

老套路和Application相似,通過傳送訊息,這裡發了一個LAUNCH_ACTIVITY訊息,繼續看看訊息接收地方做了啥事情:

public void handleMessage(Message msg) {
    if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
    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);
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        } break;
        ……
    }
    if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
}
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    ……
    // 關鍵程式碼
    Activity a = performLaunchActivity(r, customIntent);
    ……
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent){
    ……
    Activity activity = null;
    try {
        // 關鍵程式碼1:通過反射建立activity例項
        java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
        activity = mInstrumentation.newActivity(
                cl, component.getClassName(), r.intent);
        StrictMode.incrementExpectedActivityCount(activity.getClass());
        r.intent.setExtrasClassLoader(cl);
        r.intent.prepareToEnterProcess();
        if (r.state != null) {
            r.state.setClassLoader(cl);
        }
    } catch (Exception e) {
        if (!mInstrumentation.onException(activity, e)) {
            throw new RuntimeException(
                "Unable to instantiate activity " + component
                + ": " + e.toString(), e);
        }
    }

    try {
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);
        ……
        if (activity != null) {
            Context appContext = createBaseContextForActivity(r, activity);
            CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
            Configuration config = new Configuration(mCompatConfiguration);
            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
                    + r.activityInfo.name + " with config " + config);
            // 關鍵程式碼2:對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);
            if (customIntent != null) {
                activity.mIntent = customIntent;
            }
            r.lastNonConfigurationInstances = null;
            activity.mStartedActivity = false;
            int theme = r.activityInfo.getThemeResource();
            if (theme != 0) {
                activity.setTheme(theme);
            }
            activity.mCalled = false;
            // 關鍵程式碼3:activity的onCreate的回撥
            if (r.isPersistable()) {
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
            } else {
                mInstrumentation.callActivityOnCreate(activity, r.state);
            }
            ……
    } catch (SuperNotCalledException e) {
        throw e;
    } catch (Exception e) {
        ……
    }
    return activity;
}

請看關鍵程式碼1,內部是通過反射建立activity例項:

public Activity newActivity(ClassLoader cl, String className,
        Intent intent)
        throws InstantiationException, IllegalAccessException,
        ClassNotFoundException {
    return (Activity)cl.loadClass(className).newInstance();
}

請看關鍵程式碼2,內部主要是對Activity進行了初始化了一些重要的資料,如Window的建立和關聯就是這此處完成:

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) {
    attachBaseContext(context);

    mFragments.attachActivity(this, mContainer, null);
    mWindow = PolicyManager.makeNewWindow(this);
    mWindow.setCallback(this);
    mWindow.setOnWindowDismissedCallback(this);
    mWindow.getLayoutInflater().setPrivateFactory(this);
    if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
        mWindow.setSoftInputMode(info.softInputMode);
    }
    if (info.uiOptions != 0) {
        mWindow.setUiOptions(info.uiOptions);
    }
    mUiThread = Thread.currentThread();

    mMainThread = aThread;
    mInstrumentation = instr;
    mToken = token;
    mIdent = ident;
    mApplication = application;
    mIntent = intent;
    mReferrer = referrer;
    mComponent = intent.getComponent();
    mActivityInfo = info;
    mTitle = title;
    mParent = parent;
    mEmbeddedID = id;
    mLastNonConfigurationInstances = lastNonConfigurationInstances;
    if (voiceInteractor != null) {
        if (lastNonConfigurationInstances != null) {
            mVoiceInteractor = lastNonConfigurationInstances.voiceInteractor;
        } else {
            mVoiceInteractor = new VoiceInteractor(voiceInteractor, this, this,
                    Looper.myLooper());
        }
    }

    mWindow.setWindowManager(
            (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
            mToken, mComponent.flattenToString(),
            (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
    if (mParent != null) {
        mWindow.setContainer(mParent.getWindow());
    }
    mWindowManager = mWindow.getWindowManager();
    mCurrentConfig = config;
}

再來看關鍵程式碼3,這套路跟Application也是很相似的,它是activity的onCreate的回撥的處理:

Instrumentation.java

public void callActivityOnCreate(Activity activity, Bundle icicle,
        PersistableBundle persistentState) {
    prePerformCreate(activity);
    // 關鍵程式碼
    activity.performCreate(icicle, persistentState);
    postPerformCreate(activity);
}

Activity.java

final void performCreate(Bundle icicle, PersistableBundle persistentState) {
    onCreate(icicle, persistentState);
    mActivityTransitionState.readState(icicle);
    performCreateCommon();
}

可以看到,最後的確是呼叫了Activity的OnCreate方法。就這樣,Activity的啟動流程就介紹完了。

總結

還是那句,看原始碼真的會讓人感到乏味和無趣,整個過程真的是又長又臭,但主要記住關鍵點其實就足夠了:

  1. Android中app在Application建立後,第一個呼叫的是attachBaseContext()方法,然後再是onCreate()方法。
  2. Android中app在Activity建立後,第一個呼叫的是onCreate()方法