【源碼解析】Activity的啟動(dòng)過(guò)程

在平時(shí)啟動(dòng)Activity時(shí)厂榛,我們常用的是在Activity中直接調(diào)用startActivity(intent)就可以啟動(dòng)Activity蛉签,或者是通過(guò)context來(lái)啟動(dòng)Activity。歸根結(jié)底調(diào)用的是ContextImpl類(lèi)的startActivity(intent)方法投队。所以我們直接從ContextImpl的startActivity(intent)方法開(kāi)始畜伐,而startActivity(intent)方法最終調(diào)用了startActivity(intent, bundle)吗讶。以下是源碼(本篇文章的源碼的基于Android 26的袖裕,不同版本代碼間可能有些出入曹抬,但是原理是一樣的):

@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.
    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0
            && 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);
}

判斷了一下如果是從外部啟動(dòng)Activity,但是卻沒(méi)有設(shè)置Intent 的flag為FLAG_ACTIVITY_NEW_TASK的急鳄,會(huì)拋出異常谤民。我們平時(shí)也會(huì)用Application作為Context去啟動(dòng)Activity堰酿,如果沒(méi)有設(shè)置Intent的flag為FLAG_ACTIVITY_NEW_TASK,會(huì)拋出上面的異常赖临,這點(diǎn)是需要注意的胞锰。
正常的流程下是走mMainThread.getInstrumentation().execStartActivity方法灾锯。先記住這一步兢榨,到時(shí)候還要回來(lái)看。我們先去看一下Activity的startActivity方法和Context的startActivity方法有什么區(qū)別顺饮,Activity的startActivity方法最終調(diào)用了startActivityForResult的方法吵聪,我們直接看該方法好了:

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
        @Nullable Bundle options) {
    if (mParent == null) {
        options = transferSpringboardActivityOptions(options);
        Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, this,
                intent, requestCode, options);
        if (ar != null) {
            mMainThread.sendActivityResult(
                mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                ar.getResultData());
        }
        if (requestCode >= 0) {        
            mStartedActivity = true;
        }

        cancelInputsAndStartExitTransition(options);
    } else {
        if (options != null) {
            mParent.startActivityFromChild(this, intent, requestCode, options);
        } else {       
            mParent.startActivityFromChild(this, intent, requestCode);
        }
    }
}

如果mParent不為空,則執(zhí)行mParent的startActivityFromChild方法:

public void startActivityFromChild(@NonNull Activity child, @RequiresPermission Intent intent,
        int requestCode, @Nullable Bundle options) {
    options = transferSpringboardActivityOptions(options);
    Instrumentation.ActivityResult ar =
        mInstrumentation.execStartActivity(
            this, mMainThread.getApplicationThread(), mToken, child,
            intent, requestCode, options);
    if (ar != null) {
        mMainThread.sendActivityResult(
            mToken, child.mEmbeddedID, requestCode,
            ar.getResultCode(), ar.getResultData());
    }
    cancelInputsAndStartExitTransition(options);
}

這里的執(zhí)行邏輯和上面mParent為空時(shí)的執(zhí)行邏輯是一樣的兼雄。都是調(diào)用了Instrumentation類(lèi)的execStartActivity方法吟逝。看到這里赦肋,我們?cè)賹?duì)比一下最開(kāi)始講到的ContextImpl里面的startActivity方法块攒,同樣都是執(zhí)行了Instrumentation類(lèi)的execStartActivity方法。所以我們就集中地看Instrumentation類(lèi)的execStartActivity方法吧佃乘,Instrumentation類(lèi)的execStartActivity方法有很多個(gè)重構(gòu)的方法囱井,它們的邏輯都是一樣的,所以我們就拿其中的一個(gè)看好了趣避。源碼如下:

public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
    IApplicationThread whoThread = (IApplicationThread) contextThread;
    Uri referrer = target != null ? target.onProvideReferrer() : null;
    if (referrer != null) {
        intent.putExtra(Intent.EXTRA_REFERRER, referrer);
    }
    if (mActivityMonitors != null) {
        synchronized (mSync) {
            final int N = mActivityMonitors.size();
            for (int i=0; i<N; i++) {
                final ActivityMonitor am = mActivityMonitors.get(i);
                ActivityResult result = null;
                if (am.ignoreMatchingSpecificIntents()) {
                    result = am.onStartActivity(intent);
                }
                if (result != null) {
                    am.mHits++;
                    return result;
                } else if (am.match(who, null, intent)) {
                    am.mHits++;
                    if (am.isBlocking()) {
                        return requestCode >= 0 ? am.getResult() : null;
                    }
                    break;
                }
            }
        }
    }
    try {
        intent.migrateExtraStreamToClipData();
        intent.prepareToLeaveProcess(who);
        int result = ActivityManager.getService()
            .startActivity(whoThread, who.getBasePackageName(), 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;
}

源碼有點(diǎn)長(zhǎng)庞呕,我們挑重點(diǎn)來(lái)看,和啟動(dòng)Activity相關(guān)的就是ActivityManager.getService().startActivity方法程帕。該方法調(diào)用了ActivityManager.getService()的startActivity方法住练。在進(jìn)入ActivityManager之前,先看一下checkStartActivityResult方法:

public static void checkStartActivityResult(int res, Object intent) {
        if (!ActivityManager.isStartResultFatalError(res)) {
            return;
        }

        switch (res) {
            case ActivityManager.START_INTENT_NOT_RESOLVED:
            case ActivityManager.START_CLASS_NOT_FOUND:
                if (intent instanceof Intent && ((Intent)intent).getComponent() != null)
                    throw new ActivityNotFoundException(
                            "Unable to find explicit activity class "
                            + ((Intent)intent).getComponent().toShortString()
                            + "; have you declared this activity in your AndroidManifest.xml?");
                throw new ActivityNotFoundException(
                        "No Activity found to handle " + intent);
            case ActivityManager.START_PERMISSION_DENIED:
                throw new SecurityException("Not allowed to start activity "
                        + intent);
            case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
                throw new AndroidRuntimeException(
                        "FORWARD_RESULT_FLAG used while also requesting a result");
            case ActivityManager.START_NOT_ACTIVITY:
                throw new IllegalArgumentException(
                        "PendingIntent is not an activity");
            case ActivityManager.START_NOT_VOICE_COMPATIBLE:
                throw new SecurityException(
                        "Starting under voice control not allowed for: " + intent);
            case ActivityManager.START_VOICE_NOT_ACTIVE_SESSION:
                throw new IllegalStateException(
                        "Session calling startVoiceActivity does not match active session");
            case ActivityManager.START_VOICE_HIDDEN_SESSION:
                throw new IllegalStateException(
                        "Cannot start voice activity on a hidden session");
            case ActivityManager.START_ASSISTANT_NOT_ACTIVE_SESSION:
                throw new IllegalStateException(
                        "Session calling startAssistantActivity does not match active session");
            case ActivityManager.START_ASSISTANT_HIDDEN_SESSION:
                throw new IllegalStateException(
                        "Cannot start assistant activity on a hidden session");
            case ActivityManager.START_CANCELED:
                throw new AndroidRuntimeException("Activity could not be started for "
                        + intent);
            default:
                throw new AndroidRuntimeException("Unknown error code "
                        + res + " when starting " + intent);
        }
    }

是不是看到了一個(gè)很熟悉的異常愁拭,have you declared this activity in your AndroidManifest.xml?讲逛,這個(gè)異常的意思是我們沒(méi)有在AndroidManifest中注冊(cè)我們的Activity,所以拋出異常了岭埠。這說(shuō)明了啟動(dòng)的Activity會(huì)通過(guò)ActivityManagerService進(jìn)行一些校驗(yàn)盏混,如果不符合要求就會(huì)拋出異常。好了枫攀,讓我們繼續(xù)進(jìn)入ActivityManager類(lèi)可以看到getService方法如下:

public static IActivityManager getService() {
    return IActivityManagerSingleton.get();
}

它又調(diào)用了IActivityManagerSingleton類(lèi)的get()方法括饶,而IActivityManagerSingleton類(lèi)是一個(gè)Singleton類(lèi)型的靜態(tài)單例類(lèi),如下所示:

private static final Singleton<IActivityManager> IActivityManagerSingleton =
    new Singleton<IActivityManager>() {
        @Override
        protected IActivityManager create() {
            final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
            final IActivityManager am = IActivityManager.Stub.asInterface(b);
            return am;
        }
    };

我們看一下Singleton類(lèi)的定義:

public abstract class Singleton<T> {
    private T mInstance;

    protected abstract T create();

    public final T get() {
        synchronized (this) {
            if (mInstance == null) {
                mInstance = create();
            }
            return mInstance;
        }
    }
}

其中的get()方法返回了mInstance對(duì)象来涨,而mInstance對(duì)象又由create()方法創(chuàng)建的图焰。我們可以看到上面IActivityManagerSingleton對(duì)象的create()方法創(chuàng)建了一個(gè)IActivityManager類(lèi)型的對(duì)象。而IActivityManager是一個(gè)接口蹦掐,其具體的實(shí)現(xiàn)類(lèi)是ActivityManagerService技羔,所以最終調(diào)用的是ActivityManagerService的startActivity方法:

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

又調(diào)用了startActivityAsUser方法僵闯,而startActivityAsUser方法又調(diào)用了其重構(gòu)的同名方法,而其重構(gòu)的方法又調(diào)用了ActivityStarter的startActivityMayWait方法藤滥,經(jīng)過(guò)內(nèi)部多次調(diào)用鳖粟,然后又調(diào)用了ActivityStackSupervisor類(lèi)的方法,經(jīng)過(guò)了ActivityStarter類(lèi)和ActivityStackSupervisor類(lèi)的多次調(diào)用拙绊,最后執(zhí)行的是ActivityStackSupervisor類(lèi)中的realStartActivityLocked方法向图,那么我們直接看這個(gè)方法吧:

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);
    ...省略
}

在realStartActivityLocked方法中調(diào)用了app.thread. scheduleLaunchActivity方法,而app.thread的類(lèi)型是IApplicationThread标沪,其實(shí)現(xiàn)類(lèi)是ActivityThread內(nèi)部類(lèi)ApplicationThread榄攀,所以我們?nèi)pplicationThread中找到scheduleLaunchActivity方法:

@Override
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) {

    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;

    r.overrideConfig = overrideConfig;
    updatePendingConfiguration(curConfig);

    sendMessage(H.LAUNCH_ACTIVITY, r);
}

最后調(diào)用了sendMessage方法,而在sendMessage方法又調(diào)用了其同名重構(gòu)方法sendMessage:

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

最后通過(guò)調(diào)用了mH的sendMessage方法將一個(gè)Message對(duì)象添加到消息隊(duì)列金句,因?yàn)閙H的類(lèi)型的Handler類(lèi)檩赢,所以最終會(huì)在mH的handleMessage方法中處理該消息,我們看一下handleMessage方法中對(duì)于msg.what為H.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, "LAUNCH_ACTIVITY");
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        } break;
        ...省略
    }
}

其中又調(diào)用了handleLaunchActivity方法:

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
    unscheduleGcIdler();
    mSomeActivitiesChanged = true;

    if (r.profilerInfo != null) {
        mProfiler.setProfiler(r.profilerInfo);
        mProfiler.startProfiling();
    }

    // Make sure we are running with the most recent config.
    handleConfigurationChanged(null, null);

    if (localLOGV) Slog.v(
        TAG, "Handling launch of " + r);

    // Initialize before creating the activity
    WindowManagerGlobal.initialize();

    Activity a = performLaunchActivity(r, customIntent);

    if (a != null) {
        r.createdConfig = new Configuration(mConfiguration);
        reportSizeConfigurations(r);
        Bundle oldState = r.state;
        handleResumeActivity(r.token, false, r.isForward,
                !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);

        if (!r.activity.mFinished && r.startsNotResumed) {      
            performPauseActivityIfNeeded(r, reason);

            if (r.isPreHoneycomb()) {
                r.state = oldState;
            }
        }
    } else {
        // If there was an error, for any reason, tell the activity manager to stop us.
        try {
            ActivityManager.getService()
                .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                        Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
    }
}

其中調(diào)用了performLaunchActivity方法創(chuàng)建了一個(gè)Activity對(duì)象违寞,然后回調(diào)Activity的生命周期方法贞瞒,我們看一下performLaunchActivity方法:

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");

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

    ContextImpl appContext = createBaseContextForActivity(r);
    Activity activity = null;
    try {
        java.lang.ClassLoader cl = appContext.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 (localLOGV) Slog.v(TAG, "Performing launch of " + r);
        if (localLOGV) Slog.v(
                TAG, r + ": app=" + app
                + ", appName=" + app.getPackageName()
                + ", pkg=" + r.packageInfo.getPackageName()
                + ", comp=" + r.intent.getComponent().toShortString()
                + ", dir=" + r.packageInfo.getAppDir());

        if (activity != null) {
            CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
            Configuration config = new Configuration(mCompatConfiguration);
            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;
            }
            appContext.setOuterContext(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.configCallback);

            if (customIntent != null) {
                activity.mIntent = customIntent;
            }
            r.lastNonConfigurationInstances = null;
            checkAndBlockForNetworkAccess();
            activity.mStartedActivity = false;
            int theme = r.activityInfo.getThemeResource();
            if (theme != 0) {
                activity.setTheme(theme);
            }

            activity.mCalled = false;
            if (r.isPersistable()) {
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
            } else {
                mInstrumentation.callActivityOnCreate(activity, r.state);
            }
            if (!activity.mCalled) {
                throw new SuperNotCalledException(
                    "Activity " + r.intent.getComponent().toShortString() +
                    " did not call through to super.onCreate()");
            }
            r.activity = activity;
            r.stopped = true;
            if (!r.activity.mFinished) {
                activity.performStart();
                r.stopped = false;
            }
            if (!r.activity.mFinished) {
                if (r.isPersistable()) {
                    if (r.state != null || r.persistentState != null) {
                        mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
                                r.persistentState);
                    }
                } else if (r.state != null) {
                    mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
                }
            }
            if (!r.activity.mFinished) {
                activity.mCalled = false;
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnPostCreate(activity, r.state,
                            r.persistentState);
                } else {
                    mInstrumentation.callActivityOnPostCreate(activity, r.state);
                }
                if (!activity.mCalled) {
                    throw new SuperNotCalledException(
                        "Activity " + r.intent.getComponent().toShortString() +
                        " did not call through to super.onPostCreate()");
                }
            }
        }
        r.paused = true;

        mActivities.put(r.token, r);

    } catch (SuperNotCalledException e) {
        throw e;

    } catch (Exception e) {
        if (!mInstrumentation.onException(activity, e)) {
            throw new RuntimeException(
                "Unable to start activity " + component
                + ": " + e.toString(), e);
        }
    }

    return activity;
}

該方法的源碼有點(diǎn)長(zhǎng),我們分層次來(lái)看:
1趁曼、首先通過(guò)調(diào)用mInstrumentation.newActivity方法創(chuàng)建了一個(gè)Activity對(duì)象军浆,而mInstrumentation.newActivity方法創(chuàng)建對(duì)象的過(guò)程也很簡(jiǎn)單,直接通過(guò)反射創(chuàng)建一個(gè)新的對(duì)象彰阴,如下所示:

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

2瘾敢、接著通過(guò)調(diào)用r.packageInfo.makeApplication方法判斷Application對(duì)象是否存在,存在則返回尿这,不存在則新建一個(gè)Application對(duì)象并回調(diào)其onCreate方法:

public Application makeApplication(boolean forceDefaultAppClass,
        Instrumentation instrumentation) {
    if (mApplication != null) {
        return mApplication;
    }

    ...省略

    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;

    if (instrumentation != null) {
        try {
            instrumentation.callApplicationOnCreate(app);
        } catch (Exception e) {
            if (!instrumentation.onException(app, e)) {
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                throw new RuntimeException(
                    "Unable to create application " + app.getClass().getName()
                    + ": " + e.toString(), e);
            }
        }
    }

    ...省略

    return app;
}

3簇抵、回調(diào)Activity對(duì)象的attach、onCreate方法:

if (activity != null) {
    CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
    Configuration config = new Configuration(mCompatConfiguration);
    if (r.overrideConfig != null) {
        config.updateFrom(r.overrideConfig);
    }
    ...省略
    appContext.setOuterContext(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.configCallback);

    ...省略
    if (r.isPersistable()) {
        mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
    } else {
        mInstrumentation.callActivityOnCreate(activity, r.state);
    }
    if (!activity.mCalled) {
        throw new SuperNotCalledException(
            "Activity " + r.intent.getComponent().toShortString() +
            " did not call through to super.onCreate()");
    }
    r.activity = activity;
}

到這里Activity就啟動(dòng)起來(lái)了射众。下面我們來(lái)回顧一下上面的所有步驟流程:
1碟摆、首先我們要啟動(dòng)的Activity會(huì)去ActivityManagerService中校檢是否合法,如果不合法則拋出異常叨橱。
2典蜕、然后通過(guò)回調(diào)ActivityThread中內(nèi)部類(lèi)ApplicationThread的scheduleLaunchActivity方法并發(fā)送一個(gè)消息到ActivityThread中的內(nèi)部類(lèi)H中,而H是一個(gè)Handler類(lèi)罗洗。
3愉舔、最后通過(guò)反射創(chuàng)建Activity對(duì)象及Application對(duì)象,并回調(diào)其中的生命周期方法伙菜,從而將Activity啟動(dòng)起來(lái)轩缤。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子火的,更是在濱河造成了極大的恐慌壶愤,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件馏鹤,死亡現(xiàn)場(chǎng)離奇詭異征椒,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)湃累,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)勃救,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人脱茉,你說(shuō)我怎么就攤上這事剪芥。” “怎么了琴许?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)溉躲。 經(jīng)常有香客問(wèn)我榜田,道長(zhǎng),這世上最難降的妖魔是什么锻梳? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任箭券,我火速辦了婚禮,結(jié)果婚禮上疑枯,老公的妹妹穿的比我還像新娘辩块。我一直安慰自己,他們只是感情好荆永,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布废亭。 她就那樣靜靜地躺著,像睡著了一般具钥。 火紅的嫁衣襯著肌膚如雪豆村。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,144評(píng)論 1 285
  • 那天骂删,我揣著相機(jī)與錄音掌动,去河邊找鬼。 笑死宁玫,一個(gè)胖子當(dāng)著我的面吹牛粗恢,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播欧瘪,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼眷射,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起凭迹,我...
    開(kāi)封第一講書(shū)人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤罚屋,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后嗅绸,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體脾猛,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年鱼鸠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了猛拴。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蚀狰,死狀恐怖愉昆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情麻蹋,我是刑警寧澤跛溉,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站扮授,受9級(jí)特大地震影響芳室,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜刹勃,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一堪侯、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧荔仁,春花似錦伍宦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至掌呜,卻和暖如春滓玖,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背质蕉。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工势篡, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人模暗。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓禁悠,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親兑宇。 傳聞我的和親對(duì)象是個(gè)殘疾皇子碍侦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容