天天看点

Android Activity的启动过程

每天看郭神的公众号文章已经成了我的一个习惯,前段时间看到一篇文章,ActivityThread的main()方法究竟做了什么工作?main方法代码并不长,但行行珠玑。

我也打开源码去看了main方法,之后还鼠标滑滑滑大致看了ActivityThread,发现了performLaunchActivity方法,这个方法分明就是用来启动Activity的,那么这个performLaunchActivity方法在哪里被调用了呢?Activity的启动过程从哪里开始?

Activity的启动过程真的很复杂,先看一张图大概了解一下,其中用灰色背景框起来的是在同一个类的方法,如下图:

Android Activity的启动过程

那接下来就从源码的角度来分析Activity的启动过程。

当然是从Activity的startActivity方法开始的,

@Override
public void startActivity(Intent intent) {
    this.startActivity(intent, null);
}
           

使用this关键字调用 了startActivity方法的两个参数的重载。如下:

@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
    if (options != null) {
        startActivityForResult(intent, -, options);
    } else {
        // Note we want to go through this call for compatibility with
        // applications that may have overridden the method.
        startActivityForResult(intent, -);
    }
}
           

不管怎样,都会调用startActivityForResult方法。并将intent传进。

public void startActivityForResult(Intent intent, int requestCode) {
    startActivityForResult(intent, requestCode, null);
}
           

转到了startActivityForResult三个参数的重载方法,那就跟进瞧瞧,源码如下:

public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
    if (mParent == null) {
        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 >= ) {
            // If this start is requesting a result, we can avoid making
            // the activity visible until the result is received.  Setting
            // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
            // activity hidden during this time, to avoid flickering.
            // This can only be done when a result is requested because
            // that guarantees we will get information back when the
            // activity is finished, no matter what happens to it.
            mStartedActivity = true;
        }

        cancelInputsAndStartExitTransition(options);
        // TODO Consider clearing/flushing other event sources and events for child windows.
    } else {
        if (options != null) {
            mParent.startActivityFromChild(this, intent, requestCode, options);
        } else {

        //代码省略
        }
    }
}
           

先是判断mParent是否为空。那么mParent是什么呢?Activity中有一个isChild方法如下:

/** Is this activity embedded inside of another activity? */
public final boolean isChild() {
    return mParent != null;
}
           

从注释中可以知道mParent是一个ActivityGroup来的,可以嵌入子Activity的,这个我没用过。在我刚学Android的时候Fragment已经很流行了。

那我们回到startActivityForResult方法直接看到mParent == null的情况即可。可以看到内部调用了Instrumentation的execStartActivity方法,从字眼上看这个方法就是用来启动Activity的吧。

这个execStartActivity方法的第二个参数mMainThread.getApplicationThread()。是一个ApplicationThread对象。ApplicationThread继承自ApplicationThreadNative,而ApplicationThreadNative继承自Binder并实现了IApplicationThread接口。也就是说ApplicationThread是一个Binder,而且是IApplicationThread的实现类,IApplicationThread接口有很多启动Activity,Service,注册广播等方法,很强大。那么他的实现类ApplicationThread就具备了这些功能。好,到这里先。

那现在跟进看看Instrumentation的execStartActivity方法内部实现,

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;

    //代码省略

    try {
        intent.migrateExtraStreamToClipData();
        intent.prepareToLeaveProcess();
        int result = ActivityManagerNative.getDefault()
            .startActivity(whoThread, who.getBasePackageName(), intent,
                    intent.resolveTypeIfNeeded(who.getContentResolver()),
                    token, target != null ? target.mEmbeddedID : null,
                    requestCode, , null, options);
        checkStartActivityResult(result, intent);
    } catch (RemoteException e) {
        throw new RuntimeException("Failure from system", e);
    }
    return null;
}
           

看,从execStartActivity方法的参数列表也可以看出,刚才传进的ApplicationThread是一个Binder。

那么现在分析下execStartActivity方法的内部实现,找到了startActivity的字眼了,在try/catch代码块,这个从抛出的异常RemoteException,也可以推断是一个跨进程操作了。先不管。从try/catch代码块中可以看到ActivityManagerNative.getDefault()调用了startActivity的方法去启动Activity,

返回了一个result结果,之后将result传进checkStartActivityResult方法,这个方法是用来检查Activity启动结果的,如下:

public static void checkStartActivityResult(int res, Object intent) {
    if (res >= ActivityManager.START_SUCCESS) {
        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);

    //代码省略

    }
}
           

Unable to find explicit activity class have you declared this activity in your AndroidManifest.xml? No Activity found to handle,从这些熟悉的异常信息我们可以知道,当没有在AndroidManifest注册Activity,到了checkStartActivityResult方法就会抛出异常。

好,那现在回到刚才分析的ActivityManagerNative.getDefault()调用startActivity方法,现在不知道怎么跟踪源码了,因为我们不知道ActivityManagerNative.getDefault()是什么?

ActivityManagerNative是一个抽象类来的,继承自Binder并实现了IActivityManager接口。而ActivirtManagerService是继承自ActivityManagerNative这个抽象类的,也就是说ActivirtManagerService是IActivityManager的实现类。

那么我们先看到ActivityManagerNative的getDefault方法,

/**
 * Retrieve the system's default/global activity manager.
 */
static public IActivityManager getDefault() {
    return gDefault.get();
}
           

那么gDefault又是什么?

private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
    protected IActivityManager create() {
        IBinder b = ServiceManager.getService("activity");
        if (false) {
            Log.v("ActivityManager", "default service binder = " + b);
        }
        IActivityManager am = asInterface(b);
        if (false) {
            Log.v("ActivityManager", "default service = " + am);
        }
        return am;
    }
};
           

gDefault其实是一个单例类,接收泛型参数。有一个create方法。那么就看看这个Singleton单例类是什么样的。

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

如果泛型对象为空,就调用create方法创建,不为空则返回,那么我们现在看到刚才的create方法的实现就好了。

ServiceManager调用了getService方法,这是什么意思呢?这个不深入了,其实ServiceManager.getService(“activity”)返回的就是IActivityManager 的实现类ActivirtManagerService。

而ServiceManager的内部,使用了集合来存储各种系统服务,而这种用集合存储服务的方法也是一种单例模式。有兴趣的同学可以去探探究竟。

那么ActivityManagerNative.getDefault()返回的是一个ActivirtManagerService,简称AMS。我们现在看到AMS的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 options) {
    return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
        resultWho, requestCode, startFlags, profilerInfo, options,
        UserHandle.getCallingUserId());
}
           

继续跟进startActivityAsUser方法

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

同样是锁定startActivity字眼,在最后的return语句。可以看到,调用了ActivityStackSupervisor的startActivityMayWait方法来启动Activity,这时已经到了到了ActivityStackSupervisor类了。现在回忆下开篇看的那张描述Activity启动过程的图,思路会更清晰。

那继续跟进。探探ActivityStackSupervisor的startActivityMayWait方法,

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 config,
        Bundle options, boolean ignoreTargetSecurity, int userId,
        IActivityContainer iContainer, TaskRecord inTask) {
    // Refuse possible leaked file descriptors
    if (intent != null && intent.hasFileDescriptors()) {
        throw new IllegalArgumentException("File descriptors passed in Intent");
    }
    boolean componentSpecified = intent.getComponent() != null;

    // Don't modify the client's object!
    intent = new Intent(intent);

        //代码省略

        int res = startActivityLocked(caller, intent, resolvedType, aInfo,
                voiceSession, voiceInteractor, resultTo, resultWho,
                requestCode, callingPid, callingUid, callingPackage,
                realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity,
                componentSpecified, null, container, inTask);

        //代码省略

        return res;
    }
}
           

这个方法代码其实是很长的啊,总之会转到startActivityLocked方法。那我们继续看到startActivityLocked方法,

final int startActivityLocked(IApplicationThread caller,
        Intent intent, String resolvedType, ActivityInfo aInfo,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        IBinder resultTo, String resultWho, int requestCode,
        int callingPid, int callingUid, String callingPackage,
        int realCallingPid, int realCallingUid, int startFlags, Bundle options,
        boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
        ActivityContainer container, TaskRecord inTask) {
    int err = ActivityManager.START_SUCCESS;

    //代码省略

    ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
            intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
            requestCode, componentSpecified, voiceSession != null, this, container, options);

//代码省略

    err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
            startFlags, true, options, inTask);

    if (err < ) {
        // If someone asked to have the keyguard dismissed on the next
        // activity start, but we are not actually doing an activity
        // switch...  just dismiss the keyguard now, because we
        // probably want to see whatever is behind it.
        notifyActivityDrawnForKeyguard();
    }
    return err;
}
           

startActivityLocked方法又会调用startActivityUncheckedLocked方法。

startActivityUncheckedLocked方法如下:

final int startActivityUncheckedLocked(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
        boolean doResume, Bundle options, TaskRecord inTask) {
    final Intent intent = r.intent;
    final int callingUid = r.launchedFromUid;

        //代码省略
          // If the activity being launched is the same as the one currently
        // at the top, then we need to check if it should only be launched
        // once.
        ActivityStack topStack = mFocusedStack;
        ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
        if (top != null && r.resultTo == null) {
            if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
                if (top.app != null && top.app.thread != null) {
                    if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 
                        || launchSingleTop || launchSingleTask) {
                        ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
                                top.task);
                        // For paranoia, make sure we have correctly
                        // resumed the top activity.
                        topStack.mLastPausedActivity = null;
                        if (doResume) {
                            resumeTopActivitiesLocked();
                        }
                        ActivityOptions.abort(options);
                        if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != ) {
                            // We don't need to start a new activity, and
                            // the client said not to do anything if that
                            // is the case, so this is it!
                            return ActivityManager.START_RETURN_INTENT_TO_CALLER;
                        }
                        top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
                        return ActivityManager.START_DELIVERED_TO_TOP;
                    }
                }
            }
        }

        //代码省略


}
           

可以看到startActivityUncheckedLocked方法内部,在if(doResume)的判断,会调用resumeTopActivitiesLocked方法。

那就跟进resumeTopActivitiesLocked方法

boolean resumeTopActivitiesLocked() {
    return resumeTopActivitiesLocked(null, null, null);
}
           

继续点进去

boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
        Bundle targetOptions) {
    if (targetStack == null) {
        targetStack = mFocusedStack;
    }
    // Do targetStack first.
    boolean result = false;
    if (isFrontStack(targetStack)) {
        result = targetStack.resumeTopActivityLocked(target, targetOptions);
    }

    for (int displayNdx = mActivityDisplays.size() - ; displayNdx >= ; --displayNdx) {
        final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
        for (int stackNdx = stacks.size() - ; stackNdx >= ; --stackNdx) {
            final ActivityStack stack = stacks.get(stackNdx);
            if (stack == targetStack) {
                // Already started above.
                continue;
            }
            if (isFrontStack(stack)) {
                stack.resumeTopActivityLocked(null);
            }
        }
    }
    return result;
}
           

这里会调用ActivityStack的resumeTopActivityLocked方法,此时已经来到了ActivityStack了。

final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
    if (mStackSupervisor.inResumeTopActivity) {
        // Don't even start recursing.
        return false;
    }

    boolean result = false;
    try {
        // Protect against recursion.
        mStackSupervisor.inResumeTopActivity = true;
        if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
            mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
            mService.updateSleepIfNeededLocked();
        }
        result = resumeTopActivityInnerLocked(prev, options);
    } finally {
        mStackSupervisor.inResumeTopActivity = false;
    }
    return result;
}
           

看到try代码块,调用了ActivityStack的resumeTopActivityInnerLocked方法,如下:

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {

//代码省略

        if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
        mStackSupervisor.startSpecificActivityLocked(next, true, true);
    }

    if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
    return true;
}
           

resumeTopActivityInnerLocked方法内部又会调用ActivityStackSupervisor的startSpecificActivityLocked方法,现在又回到了ActivityStackSupervisor。好神奇兜了一圈又回来了

继续看到ActivityStackSupervisor的startSpecificActivityLocked方法

void startSpecificActivityLocked(ActivityRecord r,
        boolean andResume, boolean checkConfig) {
    // Is this activity's application already running?
    ProcessRecord app = mService.getProcessRecordLocked(r.processName,
            r.info.applicationInfo.uid, true);

    r.task.stack.setLaunchTime(r);

    if (app != null && app.thread != null) {
        try {
            if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 
                    || !"android".equals(r.info.packageName)) {
                // Don't add this if it is a platform component that is marked
                // to run in multiple processes, because this is actually
                // part of the framework so doesn't make sense to track as a
                // separate apk in the process.
                app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                        mService.mProcessStats);
            }
            realStartActivityLocked(r, app, 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.
    }

    mService.startProcessLocked(r.processName, r.info.applicationInfo, true, ,
            "activity", r.intent.getComponent(), false, false, true);
}
           

可以看到调用了realStartActivityLocked方法,这个方法已经开始将Activity的启动过程往AvtivityThread靠近了。那继续跟进realStartActivityLocked方法。

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, new Configuration(mService.mConfiguration),
                new Configuration(stack.mOverrideConfig), r.compat, r.launchedFromPackage,
                task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
                newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);

//代码省略

        return true;
}
           

app.thread调用了scheduleLaunchActivity方法去启动Activity。而app.thread是什么呢?

IApplicationThread thread;  // the actual proc...  may be null only if
                            // 'persistent' is true (in which case we
                            // are in the process of launching the app)
           

是一个IApplicationThread类型的实现类,那么从开始的分析可以知道就是ApplicationThread。ApplicationThread还是ActivityThread的内部类,我们现在已经回到了主线程。

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

ScheduleLaunchActivity的逻辑比较简单,封装了一些Activity组件信心,然后发送一个消息到ActivityThread。那么我们找到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;

     //代码省略

}
           

这个LAUNCH_ACTIVITY消息肯定是用于启动Activity的,可以看到调用了handleLaunchActivity方法,并将封装了待启动Activity信息的ActivityClientRecord类型的参数传入。

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {

    //代码省略

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

    Activity a = performLaunchActivity(r, customIntent);

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

        //代码省略

    }
}
           

这个方法做了一些工作,比如初始化Window,等等。

那么我们就看到核心的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);
    }

    Activity activity = null;
    try {
        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 (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) {
            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);
            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 != ) {
                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;
}
           

最核心的performLaunchActivity方法,

首先从ActivityClientRecord中获取待启动的Activity的组件信息,ActivityClientRecord里面是封装了很多东西的。如果r.packageInfo==null,调用getPackageInfo方法获取到LoadedApk实例并赋值给r.packageInfo

通过LoadedApk获取到一个类加载器,调用Instrumentation的newActivity方法通过这个类加载器创建了一个Activity对象 ,newActivity方法如下:

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

接着调用LoadedApk的makeApplication方法创建Application对象,如下:

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

    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")) {
            initializeJavaContextClassLoader();
        }
        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)) {
            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)) {
                throw new RuntimeException(
                    "Unable to create application " + app.getClass().getName()
                    + ": " + e.toString(), e);
            }
        }
    }

    //代码省略

    return app;
}
           

可以看到Application是唯一的。创建Application后,Instrumentation会调用callApplicationOnCreate去回调Application的onCreate方法。

我们可以推出:当应用启动,MainActivity的创建比Application早,但是onCreate方法的回调是Application早

再接着调用createBaseContextForActivity方法,创建了一个Context的实现类ContextImpl的对象:

private Context createBaseContextForActivity(ActivityClientRecord r, final Activity activity) {
    int displayId = Display.DEFAULT_DISPLAY;
    try {
        displayId = ActivityManagerNative.getDefault().getActivityDisplayId(r.token);
    } catch (RemoteException e) {
    }

    ContextImpl appContext = ContextImpl.createActivityContext(
            this, r.packageInfo, displayId, r.overrideConfig);
    appContext.setOuterContext(activity);
    Context baseContext = appContext;

    //代码省略

    return baseContext;
}
           

最后Activity调用attach与Application,ContextImpl等关联起来。

也调用了Instrumentation的callActivityOnCreate方法去回调了Activity的onCreate方法,至此,Activity终于诞生了

以上就是Activity的启动过程,呼!这篇文章好长。如果认真读了下来,在看回前面的图。相信你和我都会有收获。

如果你想知道当应用启动时,MainActivity的启动过程的话,可以从ActivityThread的main方法中的这两行代码跟进,

ActivityThread thread = new ActivityThread();
thread.attach(false);
           

你会发现会到ActivityStackSupervisor的realStartActivityLocked方法,之后就是进入到ApplicationThread了。和以上的分析是一样的。所以那个MainActivity的创建在Application前的推论是正确的。

转载请注明出处:http://blog.csdn.net/xyh269

继续阅读