Activity生命周期简要分析

对于源码的分析 基于android 8.0

  1. 如果一个activity 在activity栈的顶部 屏幕前台显示的话 处于运行状态
  2. 如果一个activity丢失焦点,但是仍然可见的状态(例如处于顶部activity没有全屏,或者透明的)则这个activity处于paused
    状态,这种状态下的activity在内存缺乏的时候可以被回收
  3. 如果一个activity完全被另一个activity遮挡住则处于stopped状态,在低内存的时候可能被回收掉
  4. 处于paused stopped 状态下的activity会被系统干掉在低内存的时候,重新显示的时候会调用restart方法 也会重新回复你先前保存的
    状态

全局生命周期:activity 启动的时候调用onCreate 销毁的时候调用onDestory方法 ,在onCreate 方法中初始化一些全局的状态,在onDestory
方法里面 销毁一些持久的资源,例如在 onCreate 开启下载线程 在onDestroy 方法里面停止线程


可见生命周期:activity发生在onStart 和onStop之间,在这个时候activity会出现在屏幕上,但是不属于前台界面也不能和用户交互
在这两个方法之间你可以你可以初始化 一些资源例如 可以在onStart注册改变ui的广播接收器 在onStop方法中unregister 并且activity
可以多次调用onStart 和onStop方法 在activity 显示隐藏的时候


前台生命周期:onResume 和onPause之间 activity会出现在所有其他activity之前,可以与用户交互,并且这两种状态会多次调用
例如 屏幕息屏亮屏的时候会调用onPause 和onResume 启动另一个activity 会调用onPause方法


activity 生命周期来自ApplicationContext
public class Activity extends ApplicationContext {
 *     protected void onCreate(Bundle savedInstanceState);
 *  *     protected void onStart();
 *  *     protected void onRestart();
 *  *     protected void onResume();
 *  *     protected void onPause();
 *  *     protected void onStop();
 *  *     protected void onDestroy();
 * }
  • activity启动的时候 onCreate onStart onResume
  • activity切换回主屏幕的时候 调用onPause onStop,从主屏幕切回activity时候调用onRestart onStart onResume
  • MainActivity 启动SecondActivity时候
    调用顺序MainActivity:onPause
    SecondActivity:onCreate onStart onResume
    MainActivity:onStop 如果SecondActivity透明或者没有全屏则 onStop方法不会执行
  • 从SecondActivity 返回的时候调用顺序
    SecondActivity:onPause
    MainActivity:onRestart onStart onResume
    SecondActivity:onStop onDestroy

  • 息屏的时候 会调用onPause onStop方法 点亮的时候 onRestart onStart onResume

注意点:
onPause 不要执行耗时操作 因为只有当前activity的onPause执行完下一个activity的onResume才会执行


onResume onPause和onStart onStop区别?
onResume和 onPause 成对出现的,onStart onStop 也是成对出现,在使用过程中我只需要使用其中的一对,他们的区别就是
onStart onStop 是根据用户可见性来划分的,但是,activity只是出现了用户却看不见,不能进行任何操作
onResume和onPause则是根据activity是否出现在前台划分的,activity用户可见,可以与用户交互。


当一个activityA 启动ActivityB 是ActivityA的onPause先执行还是ActivityB onResume先执行呢?
activityB会执行 ActivityStack.java 中的resumeTopActivityUncheckedLocked//Ensure that the top activity in the stack is resumed.
接着执行 resumeTopActivityInnerLocked方法中的下面代码


        // If we are currently pausing an activity, then don't do anything until that is done.
        if (!mStackSupervisor.allPausedActivitiesComplete()) {//当前activity 没有完成pause状态 不做任何事情
            if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,//直到pause状态完成
                    "resumeTopActivityLocked: Skip resume: some activity pausing.");
            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
            return false;
        }
        .....
        //获取隐藏的activity 暂停状态
        boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, false);
        if (mResumedActivity != null) {
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                    "resumeTopActivityLocked: Pausing " + mResumedActivity);
            pausing |= startPausingLocked(userLeaving, false, next, false);//如果pausing为false 则执行后面的方法
        }
        可以看见pause状态没有完成 resume代码不会执行完 

        紧接着又会执行
        mStackSupervisor.startSpecificActivityLocked(next, true, true);

        进入startSpecficActivityLocked方法中可以看见
        调用了  realStartActivityLocked(r, app, andResume, checkConfig);
        进入realStartActivityLocked方法中可以找到如下代码
            //在此处调用 启动新的activity 调用ActivityThread 中的ApplicationThread 中的scheduleLaunchActivity方法
                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);
        进入secheduleLaunchActivity找到代码
             sendMessage(H.LAUNCH_ACTIVITY, r);
        找到handleMessage方法 找到LAUNCH_ACTIVITY标志位执行的过程
        发现调用handleLaunchActivity方法 在这个方法里面有如下代码

         Activity a = performLaunchActivity(r, customIntent);//启动新的activity 执行onCreate onStart方法

        //加载完新的activity 则 执行当前activity onResume方法和
        if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            reportSizeConfigurations(r);
            Bundle oldState = r.state;
            handleResumeActivity(r.token, false, r.isForward,//让启动的activity调用onresume方法
                    !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);

            if (!r.activity.mFinished && r.startsNotResumed) {
                //actiivity启动后没有结束 但是可见却没有在前台 就执行onPause方法
                //activity 启动刚执行完onResume方法  就想让他处于onPause状态就直接执行
                // The activity manager actually wants this one to start out paused, because it
                // needs to be visible but isn't in the foreground. We accomplish this by going
                // through the normal startup (because activities expect to go through onResume()
                // the first time they run, before their window is displayed), and then pausing it.
                // However, in this case we do -not- need to do the full pause cycle (of freezing
                // and such) because the activity manager assumes it can just retain the current
                // state it has.
                performPauseActivityIfNeeded(r, reason);

                // We need to keep around the original state, in case we need to be created again.
                // But we only do this for pre-Honeycomb apps, which always save their state when
                // pausing, so we can not have them save their state when restarting from a paused
                // state. For HC and later, we want to (and can) let the state be saved as the
                // normal part of stopping the activity.
                if (r.isPreHoneycomb()) {
                    r.state = oldState;
                }
            }
        } 

         进入到performLaunchActivity中去发现会继续通过Intrumentation 调用onCreate方法 和onStart方法
        //调用Instrumentation 的onCreate方法
                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;
                //调用activity 的onStart方法 即是 instrumentation 调用callActivityOnStart mInstrumentation.callActivityOnStart(this);
                if (!r.activity.mFinished) {
                    activity.performStart();
                    r.stopped = false;
                }


        由此可见onPause 执行完以后才会执行新的activity的onResume方法 我们不要在onPause作耗时操作,并且最好为了
        不影响新的activity出现的速度,将操作写在onStop方法中去

异常情况下的activity生命周期分析:

  • 1.资源相关的系统配置发生改变导致 activity被杀死 并重新创建
    例如横屏竖屏切换时候activity 会销毁并且重新创建,
    activity 会调用onPause onStop(在onStop之前 会调用onSaveInstanceState保存activity的状态值) onDestroy
    新的activity 会被创建调用onCreate onStart 以及onResoreInstanceState 恢复状态值 onResume
    通过ActivityThread.java 中的performLaunchActivity方法下面的这段代码
    //调用activity 的onStart方法 即是 instrumentation 调用callActivityOnStart mInstrumentation.callActivityOnStart(this);
    if (!r.activity.mFinished) {
    activity.performStart();
    r.stopped = false;
    }
    if (!r.activity.mFinished) {
    if (r.isPersistable()) {//检测到activity 保存的状态不是空值 则调用onRestoreInstanceState进行恢复
    if (r.state != null || r.persistentState != null) {//保存的状态不是空值 则进行恢复
    mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
    r.persistentState);
    }
    } else if (r.state != null) {//如果
    mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
    }
    }

    可以发现onStart方法后面会执行onRestoreInstanceState方法恢复状态值
    可知道onSaveInstanceState 和onRestoreInstanceState 成对出现,activityy异常重启的时候发生调用,
    可以在其中保存一些状态值,在onRestoreInstanceState中进行恢复。
    每一个控件都有其onSaveInstanceState 和onRestoreInstanceState方法用于保存其上面的数据。

    恢复数据时候也可以在onCreate(Bundle saveInstanceState)中保存 但是需要判断变量是否为空,onRestoreInstanceState方法
    则不需要判断是否为空,因为由上面的源码发现,Bundle为空的时候不会调用onRestoreInstanceState.

  • 2.资源内存不足的时候导致低优先级的Activity被杀死
    activity 优先级从高到低排列
    1.前台Activity–正在与用户交互的Activity,优先级最高
    2.可见但非前台Activity–例如Activity弹出一个对话框,导致Activity可见但是位于后台无法与用户直接交互
    3.后台Activity 已经被暂停的Activity 比如执行onStop 优先级最低

    被会杀死的Activity 重启的时候会通过onSaveInstance 和onRestoreInstanceState 来存储恢复数据.

    系统配置内容改变,不想改变导致Activity重新创建.可以给Activity 指定configChanges属性
    例如在mainfiest.xml 指定android:configChanges=”orientation|keyboardHidden”屏幕旋转,键盘类型发生改变的时候不会到时
    Activity重新创建

猜你喜欢

转载自blog.csdn.net/gacmy/article/details/79103330