对于源码的分析 基于android 8.0
- 如果一个activity 在activity栈的顶部 屏幕前台显示的话 处于运行状态
- 如果一个activity丢失焦点,但是仍然可见的状态(例如处于顶部activity没有全屏,或者透明的)则这个activity处于paused
状态,这种状态下的activity在内存缺乏的时候可以被回收 - 如果一个activity完全被另一个activity遮挡住则处于stopped状态,在低内存的时候可能被回收掉
- 处于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重新创建