1.Activity正常状况下的生命周期的扩展学习笔记

1.1  启动Activity的时候的特殊情况
       一般来说,用户打开新的Activity或者切换到桌面的时候,回调如下: onPause->onStop。
      但是,如果Activity采用的是透明主题,那么当前的Activity是不会回调onStop的。
1.2 被回收的Activity再次启动
    当Activity被系统回收了以后再次打开,生命周期方法回调过程还是和第一次打开的一样,但是,这只是说生命周期方法一样,这不代表所有的过程都一样。
1.3 Activity生命周期的对称性
    从整个生命周期来说,onCreate对应于onDestory,onResume对应onPause ,onStart对应onRestart.其中,前者只能有一次调用,而后者可以多次调用。
1.4 onResume和onStart,onPause和onStop看似相似,却有不同
    onStart和onResume,onPause和onStop从描述上看是差不多的,但是,却是有着一些实质性的不同。
    这里面实质性的不同,就是他们所处的生命周期的不同,onStart、onStop表示的是,Activity是否可见,而onResume、onPause则是从是否运行在前台的角度来处理的,从可靠性来说,onPause是比onStop更加可靠的。

1.5 不同Activity的onResume和onPause谁先谁后?
    假设当前Activity为A,接下来要打开一个新的ActivityB,那么B的onResume和A的onPause哪个先执行呢?
    这个需要从Activity源码那边开始入手,Activity的启动过程,涉及到了Instrumentation、ActivityThread和ActivityManagerService(AMS).
    Activity的启动请求会通过Instructmentation来处理,然后Instructmentation通过Biner向AMS发出请求,AMS内部维护着一个ActivityStack,并且负责栈内的Activity的状态同步,AMS通过ActivityThread去同步Activity的状态,完成生命周期方法的调用。
    在ActivityStatck(com.android.server.am包中)中的resumeTopActivityInnerLocked方法中,有这样一段代码:
    
       // We need to start pausing the current activity so the top one
        // can be resumed...
        boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving);
        if (mResumedActivity != null) {
            pausing = true;
            startPausingLocked(userLeaving, false);
            if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Pausing " + mResumedActivity);
        }
     if (pausing) {
            if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG,
                    "resumeTopActivityLocked: Skip resume: need to start pausing");
            // At this point we want to put the upcoming activity's process
            // at the top of the LRU list, since we know we will be needing it
            // very soon and it would be a waste to let it get killed if it
            // happens to be sitting towards the end.
            if (next.app != null && next.app.thread != null) {
                // No reason to do full oom adj update here; we'll let that
                // happen whenever it needs to later.
                mService.updateLruProcessLocked(next.app, false, true);
            }
            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
            return true;
        }

    从上述代码可以看出,在新Activity启动之前,栈顶的Activity需要先onPause才会启动新的Activity.最终,在ActivityStatckSupervisor中的realStartActivityLocked方法毁调用下面这个代码:
     app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    System.identityHashCode(r), r.info,
                    new Configuration(mService.mConfiguration), r.compat,
                    app.repProcState, r.icicle, results, newIntents, !andResume,
                    mService.isNextTransitionForward(), profileFile, profileFd,
                    profileAutoStop);
    上面代码中的app类型为:ProcessRecord 。
     查看ProcessRecord 中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,上面说具体实现就是在App运行的进程中,那么可以知道这个代码的具体实现就是在ActivityThread,所以实际上调用的是ActivityThread的scheduleLauchActivity方法,而scheduleLauchActivity方法最终会完成新Activity的onCreate、onStart、onResume的调用过程,
    具体代码如下:
    
     public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
                int procState, Bundle state, List<ResultInfo> pendingResults,
                List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
                String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {

            updateProcessState(procState, false);

            ActivityClientRecord r = new ActivityClientRecord();

            r.token = token;
            r.ident = ident;
            r.intent = intent;
            r.activityInfo = info;
            r.compatInfo = compatInfo;
            r.state = state;

            r.pendingResults = pendingResults;
            r.pendingIntents = pendingNewIntents;

            r.startsNotResumed = notResumed;
            r.isForward = isForward;

            r.profileFile = profileName;
            r.profileFd = profileFd;
            r.autoStopProfiler = autoStopProfiler;

            updatePendingConfiguration(curConfig);

            queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
        }
    其中:
       queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
    上面这一行会通过一个类型为:H(命名我mH)的Handler对象接收到消息以后,在handlerLaunchActivity方法中来实现新Activity的onCreate、onStart、onResume。
    所以结论得出:旧的Activity先onPause,新的Activity再启动。

1.6 关于onPause的解释:
    Android官方文档在onPause中标注了如下:
    
      When activity B is launched in front of activity A, this callback will  be invoked on A.  B will not be created until A's {@link #onPause} returns, so be sure to not do anything lengthy here.
    意思就是不要在onPause中做耗时的操作,因为新的Activity会在onPause以后才开始显示到前台。因此耗时操作应该放在onStop中,(onStop不会影响新的Activity的显示)onPause适合做一些保存应用当前的运行数据、如果没有足够多的资源去启动新的Activity那么更要持久化数据,并且在这里最好暂停一些动画啊等消耗CPU资源的操作,使得下一个Activity可以快速启动起来。或者关闭一些唯一的单独的资源访问接口,比如说关闭调用相机。
本文参考任玉刚先生的《Anroid开发艺术探索》书和官方文档。
    
发布了30 篇原创文章 · 获赞 17 · 访问量 4万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章