Activity启动过程详解

1. 简介

本文源码基于android 27
startActivity的流程较复杂,我们这里将其过程分成三部分:

  1. startActivity-->ActivityManagerService
  2. ActivityManagerService-->ApplicationThread
  3. ApplicationThread-->Activity

这样看起来稍微简单点。

通常,我们要启动一个Activity都是直接调用startActivity,我们就从这里开始进行分析。

2. startActivity-->ActivityManagerService

ActivityManagerService,后面都简称为AMS
从调用startActivityActivityManagerService,先放张时序图:

startActivity–>AMS时序图.png

可以看到,从调用startActivityActivityManagerService之间的过程其实并不复杂。

下面开始进入源码分析,首先来看下Activity中的startActivity方法。

2.1 Activity的startActivity

    @Override
    public void startActivity(Intent intent, @Nullable Bundle options) {
        if (options != null) {
            //第二个参数为-1,表示不需要知道Activity启动的结果
            startActivityForResult(intent, -1, options);
        } else {
            startActivityForResult(intent, -1);
        }
    }

startActivity会调用startActivityForResult方法

2.2 Activity的startActivityForResult

    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) {
        if (mParent == null) {//mParent表示当前Activity的父类,一般为null
            options = transferSpringboardActivityOptions(options);
            
            //调用Instrumentation.execStartActivity(),启动新的Activity。
            //mMainThread类型为ActivityThread, 在attach()时被回调时被赋值。 
            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);
            }
        }
    }

mMainThread.getApplicationThread()会获得一个ApplicationThreadApplicationThreadActivityThread里的一个内部类,后面会用到。

接着调用InstrumentationexecStartActivity方法

2.3 Instrumentation的execStartActivity

Instrumentation类主要用来监控应用程序和系统的交互。

    public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
            
        //将contextThread转成ApplicationThread.
        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);
            //实际上这里是通过AIDL来调用AMS的startActivity方法,下面我们看下ActivityManager.getService()的代码
            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);//检查StartActivity的结果
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

我们先来看下ActivityManager.getService()中的代码

2.4 ActivityManager的getService

    public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }
    
    //创建一个单例IActivityManager
    private static final Singleton<IActivityManager> IActivityManagerSingleton =new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {
                    //获取一个关联ActivityManagerService的Binder对象
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);

                    //返回一个IActivityManager的代理对象,基于Binder机制,通过调用代理对象的方法,能够调用到ActivityManagerService相应的方法
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    
                    return am;
                }
            };

Instrumentation中通过Binder调用了AMS的startActivity方法,这样就到了AMS中去了。。

ActivitystartActivityAMSstartActivity,实际上还是比较简单的,下面就交给AMS来处理了。

3. AMS-->ApplicationThread

下面我们来看下AMSApplicationThread的过程。还是先放时序图:

AMS–>ApplicationThread时序图.png

相比于startActivity-->AMS,AMS-->ApplicationThread流程看起来复杂好多了,实际上里面大多数都是一些细节处理。我们对主要流程分析一下,细节部分就略过了。

首先来看下AMSstartActivity方法:

3.1 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 bOptions) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions,
                UserHandle.getCallingUserId());
    }

就是调用了startActivityAsUser

3.2 AMS的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 bOptions, int userId) {
        enforceNotIsolatedCaller("startActivity");//检查调用者是否合法
        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
                userId, false, ALLOW_FULL_ONLY, "startActivity", null);)//检查调用者是否有权限执行操作
        
        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
                profilerInfo, null, null, bOptions, false, userId, null, "startActivityAsUser");
    }

startActivityAsUser实际上就是检查一下调用者的权限。
然后就是调用ActivityStarterstartActivityMayWait

3.3 ActivityStarter的startActivityMayWait

ActivityStarter这个类看名字就知道是用来启动Activity的,好多启动细节都是在ActivityStarter里面处理的。我们先来看下startActivityMayWait

startActivityMayWait中主要是解析Intent的信息。
接着就是调用startActivityLocked了。后面分析。
最后如果需要返回结果,会执行mService.wait(),所以这里叫MayWait
相关代码细节这里就不分析了,抓住主要部分。

    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) {
            
            //...
            //解析Intent信息等等
            
            int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
                    aInfo, rInfo, voiceSession, voiceInteractor,
                    resultTo, resultWho, requestCode, callingPid,
                    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                    options, ignoreTargetSecurity, componentSpecified, outRecord, inTask,
                    reason);
                    
            //...
            //判断是否需要返回结果
            
            return res; 
            
    }

接着看startActivityLocked

3.4 ActivityStarter的startActivityLocked

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

        //...
    }

startActivityLocked比较简单,就是调用的startActivity

3.5 ActivityStarter的startActivity

这里的startActivity主要是检查启动权限,创建新的ActivityRecord等等,相关细节不说。

    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) {
            
        //...
        //检查启动权限
        //创建ActivityRecord
        
        return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
                options, inTask, outActivity);
    }

可以看到,这里会调另外一个重载的startActivity方法。
这里的startActivity主要是让WindowManager暂停布局。

    private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {

        int result = START_CANCELED;
        try {
            mService.mWindowManager.deferSurfaceLayout();//暂停布局
            result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, outActivity);
        //继续布局            
        //...    
    }            
            

继续看startActivityUnchecked

3.6 ActivityStarter的startActivityUnchecked

startActivityUnchecked主要处理intent携带的launch flags, 启动模式(launchMode)等等。
如果有需要,Activity任务(TaskRecord)会在这里创建。

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

然后会调用ActivityStackSupervisorresumeFocusedStackTopActivityLocked

3.7 ActivityStackSupervisor的resumeFocusedStackTopActivityLocked

ActivityStackSupervisor实际上是用来管理Activity任务栈(ActivityStack)的。
resumeFocusedStackTopActivityLocked中首先判断FocusedStack栈中是否存在target ActivityStack
然后就是调用ActivityStackresumeTopActivityUncheckedLocked

  boolean resumeFocusedStackTopActivityLocked(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {

        //...  

        if (targetStack != null && isFocusedStack(targetStack)) {
            return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
            
        //...  
    }

继续往下看

3.8 ActivityStack的resumeTopActivityUncheckedLocked

ActivityStack就是任务栈,用来管理Activity任务(TaskRecord),而上面的ActivityStackSupervisor实际上用来管理ActivityStack的。

resumeTopActivityUncheckedLocked中首先会判断是否在ResumeTopActivity状态中。

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

        boolean result = false;
        try {
            // Protect against recursion.
            mStackSupervisor.inResumeTopActivity = true;
            result = resumeTopActivityInnerLocked(prev, options);
        } finally {
            mStackSupervisor.inResumeTopActivity = false;
        }
        
        //...  
        return result;
    }

然后就是调用resumeTopActivityInnerLocked

3.9 ActivityStack的resumeTopActivityInnerLocked

resumeTopActivityInnerLocked中首先暂停当前Activity,然后启动新Activity

    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {

        //...  
        if (mResumedActivity != null) {
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                    "resumeTopActivityLocked: Pausing " + mResumedActivity);
                    
            //暂停当前activity,调用Activity的onPause
            pausing |= startPausingLocked(userLeaving, false, next, false);
        }
        //...          
        mStackSupervisor.startSpecificActivityLocked(next, true, true);//启动新activity
        //...  
    }

startPausingLocked最终会调用到AMS中,AMS再通过调用相应的方法,然后调用resumeTopActivityInnerLocked再调用到mStackSupervisor.startSpecificActivityLocked。细节不表,只需知道这中间会经过AMS就好了。

然后继续看ActivityStackSupervisorstartSpecificActivityLocked

3.10 ActivityStackSupervisor的startSpecificActivityLocked

startSpecificActivityLocked中先获取ProcessRecord(若要启动的Activity的应用已经在运行),若ProcessRecord存在则直接调用realStartActivityLocked(),否则调用 ActivityManagerServices.startProcessLocked()创建新的ProcessRecord

    void startSpecificActivityLocked(ActivityRecord r,boolean andResume, boolean checkConfig) {

        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);//获取ProcessRecord

        r.getStack().setLaunchTime(r);

        if (app != null && app.thread != null) {
            try {
                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                        || !"android".equals(r.info.packageName)) {
    
                    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);
            }
        }
        
        //创建新的ProcessRecord
        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }

继续看realStartActivityLocked

3.11 ActivityStackSupervisor的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,

                mergedConfiguration.getGlobalConfiguration(),
                mergedConfiguration.getOverrideConfiguration(), r.compat,
                r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                r.persistentState, results, newIntents, !andResume,
                mService.isNextTransitionForward(), profilerInfo);
        //...  
     }           

这里的app.thread实际上就是ApplicationThread,可以看到,兜兜转转之后终于到了ApplicationThread

4. ApplicationThread-->Activity

先来看相应的时序图:

ApplicationThread–>Activity时序图.png

从ApplicationThread到真正启动一个Activity,其实也并不是很复杂。

4.1 ApplicationThread的scheduleLaunchActivity

ApplicationThreadActivityThread的内部类。

scheduleLaunchActivity中就是将启动Activity的参数封装成ActivityClientRecord,然后调用ActivityThreadsendMessage方法。

        @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);
            
            //调用ActivityThread的sendMessage方法,发送LAUNCH_ACTIVITY信息
            sendMessage(H.LAUNCH_ACTIVITY, r);
        }
    

4.2 ActivityThread的sendMessage

sendMessage实际就是给一个名为mHHandler发信息。

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

我们看看H这个类

4.3 H类

    private class H extends Handler { //继承Handler
        public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
                case LAUNCH_ACTIVITY: {//启动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;
                case RELAUNCH_ACTIVITY: {
                   //...
                } break;
                case PAUSE_ACTIVITY: {
                    //...
                } break;
                case PAUSE_ACTIVITY_FINISHING: {
                    //...
                } break;

可以看到H里面会对各种状态进行处理。LAUNCH_ACTIVITY中会调用handleLaunchActivity,继续往下看。

4.4 ActivityThread的handleLaunchActivity

    private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
        //...
        Activity a = performLaunchActivity(r, customIntent);

        if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            reportSizeConfigurations(r);
            Bundle oldState = r.state;
            //这里最终会调用Activity的onResume生命周期
            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
        //...
        }

最终会调用performLaunchActivity

4.5 ActivityThread的performLaunchActivity

看代码中的注释吧

    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    
        //从ActivityClientRecord中获取要启动的Activity信息
        
        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在这里创建,ContextImpl是Context的具体实现
        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            
            //通过Instrumentation的newActivity使用类加载器来创建Activity对象
            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);
            }
        } 
    
        try {
            //创建Application对象,如果已经创建过,则不会重复创建,保证一个应用中只有一个Application对象;
            //实际上跟Activity一样也是在Instrumentation中使用类加载器来创建的
            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) {
                //...
                
                //attach中会建立Activity与ContextImpl的联系
                //attach中还会创建Window并与Window建立联系 可以看Activivity中的源码
                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()) {
                    //回调Activity的OnCreate
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    //回调Activity的OnCreate
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
            
        //...
        return activity;
    }   

再来看看InstrumentationcallActivityOnCreate

4.6 Instrumentation的callActivityOnCreate

    public void callActivityOnCreate(Activity activity, Bundle icicle,
            PersistableBundle persistentState) {
        prePerformCreate(activity);
        activity.performCreate(icicle, persistentState);
        postPerformCreate(activity);
    }

继续看下activity.performCreate

4.7 Activity的performCreate

    final void performCreate(Bundle icicle) {
        performCreate(icicle, null);
    }

    final void performCreate(Bundle icicle, PersistableBundle persistentState) {
        mCanEnterPictureInPicture = true;
        restoreHasCurrentPermissionRequest(icicle);
        if (persistentState != null) {
            onCreate(icicle, persistentState);//onCreate
        } else {
            onCreate(icicle);//onCreate
        }
        mActivityTransitionState.readState(icicle);

        mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
                com.android.internal.R.styleable.Window_windowNoDisplay, false);
        mFragments.dispatchActivityCreated();
        mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
    }
    

可以看到,onCreate被调用起来了。至此,Activity被启动起来了。

最后,放张总的时序图(图太大,请另外打开或保存):

startActivity时序图.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,919评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,567评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,316评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,294评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,318评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,245评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,120评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,964评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,376评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,592评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,764评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,460评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,070评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,697评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,846评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,819评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,665评论 2 354

推荐阅读更多精彩内容