Activity的生命周期
周期函数 | 状态 | 描述 | 用途 |
---|---|---|---|
onCreat | 页面不可见,创建视图,初始化数据 | 当Activity第一次创建时调用。该方法(如果有)会提供给你一个包含之前活动的冻结状态信息bundle包 | 进行一系列初始化操作,如:创建View,加载视频数据等 |
onStart | 页面可见,但是不可人机交互 | 当Activity被展示在用户眼前时调用。如果活动出现在前台紧接着是onResume(),如果活动直接隐藏则紧接着是onStop() | 该方法也不常用 |
onResume | 页面可见,可以人机交互 | 当Activity将开始与用户进行交互时调用。活动将会在活动堆栈的顶端 | 暂停后恢复我们会在该方法中进行一些操作,例如视频继续播放 |
onPause | 页面可见,但是失去焦点 | 当系统将要恢复一个之前的活动。用于提交未被存储的改动信息为持久数据,停止动画和消耗CPU的东西等 | 该方法十分重要,用来做信息持久化存储操作以及停止消耗CPU资源操作,如记录视频播放进度时间,以及暂停视频播放操作等 |
onStop | 页面不可见,完全消失 | 当另一个活动被恢复且完全覆盖该活动,而该Activity将不在展示给用户时调用。这种情况将发生在一个新的活动将被开始,一个退出的活动将被恢复,又或者该活动将要被销毁 | 界面将会隐藏或销毁,做一些重要信息或未被存储的信息的存储操作。但也不要太耗时。如存储用户信息等操作,以及用户此次观看的视频地址以及时间,便于下次打开该界面时继续播放 |
onRestart | 页面重新启动——再走onStart | 当Activity被停止后调用,在重新开始之前 | 当活动停止后重新启动该活动时调用(不常用),针对停止后重启操作 |
onDestroy | 页面完全销毁 | Activity被销毁钱最后一个被调用的方法。这个方法将会发生因为活动将会结束(调用finish()方法,或系统临时销毁该实例节约空间。isFinishing()方法区别两种场景) | 界面将要销毁,释放一些实例节约空间,如置空List集合等 |
正常的启动与关闭Activity不会调用onSaveInstanceState(Bundle)
与onRestoreInstanceState(Bundle)
,所以如果要离开该界面时,该界面的重要信息,我们要在onPause()
或onStop()
中进行存储。
Activity4种状态:
Running:拥有焦点,可以与用户交互。堆栈顶端。
Paused:失去焦点,但是依然可见。
当Activity被另一个透明或者Dialog样式的Activity覆盖时的状态。此时它依然与窗口管理器保持连接,系统继续维护其内部状态,它仍然可见,但它已经失去了焦点,故不可与用户交互。
Stopped:失去焦点,不可见。
当Activity处于此状态时,一定要保存当前数据和当前的UI状态,否则一旦Activity退出或关闭时,当前的数据和UI状态就丢失了。
Killed:Activity被杀掉以后或者被启动以前。
这时Activity已从Activity堆栈中移除,需要重新启动才可以显示和使用。如果activity处于暂停或者停止状态,系统将会在内存中终止该活动无论是结束活动或者杀死进程。当它再一次展示给用户时,它必须是完全重启并且恢复到之前的状态。
Activity的启动
1.显式启动
Intent intent=new Intent(AActivity.this,BActivity.class);
startActivity(intent);
2.隐式跳转
Intent intent=new Intent();
intent.setAction("android.intent.action.BActivity");
startActivity(intent);
<activity android:name=".jump.BActivity">
<intent-filter>
<action android:name="android.intent.action.BActivity" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
3.startActivityForResult:
启动Activity,结束后返回结果
Intent intent = new Intent();
intent.setClassName("com.creator.filemanager", "com.creator.filemanager.ui.MainActivity");
startActivityForResult(intent, SELECT_FILE_PATHS_RESULT);
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == SELECT_FILE_PATHS_RESULT) {
}
}
在跳转的页面finish前需要
setResult(SELECT_FILE_PATHS_RESULT,intent);
finish();
启动模式
standard 标准模式
Activity是由任务栈管理的,每启动一个Activity,就会被放入栈中,按返回键,就会从栈顶移除一个Activity。
standard是默认的启动模式,即标准模式,每启动一个Activity,就会创建一个新的实例。
singleTopTask 栈顶复用模式
当要启动的目标Activity已经位于栈顶时,不会创建新的实例,会复用栈顶的Activity,并且其onnewIntent()
方法会被调用;如果目标Activity不在栈顶,则跟standard一样创建新的实例。
singleTaskTask 栈内复用模式
在同一个任务栈中,如果要启动的目标Activity已经在栈中,则会复用该Acivity,并调用其onNewIntent()
方法,并且该Activity上官冕的Activity会被清除;如果栈中没有,则创建新的实例。
singleInstance 全局单例模式
全局复用,不管哪个Task栈,只要存在目标Activity,就复用。每个Activity占有一个新的Task栈。
Activity数据的保存与恢复
OnSaveInstanceState(Bundle outState)
当Activity被系统异常杀死后,会调用onSaveInstanceState(Bundle outState)
方法,此方法中有一个参数Bundle
,开发者可以使用它来保存当前的临时数据,那么到底是什么情况下此方法会被调用呢?
此方法被调用会遵循一个原则,就是系统未经你同意时销毁你的Activity,一般会有如下几种情况:
- 按下Home键
- 长按Home键,选择打开其它程序
- 按下电源键
- 从一个Activity中启动另一个Activity
- 切换屏幕方向(如果不指定configchange属性),在屏幕切换前,系统会销毁该Activity,切换完成后又会重新创建这个Activity,因此onSaveInstanceState一定会执行
OnRestaoreInstanceState
此方法和onSaveInstanceState()
不一定是成对出现的,
OnRestoreInstanceState
被调用的前提是: Activity确实被销毁了,而仅仅是有这种可能的情况下,该方法并不会被调用。
例如,当正在显示activity A的时候,用户按下HOME键回到主界面,然后用户紧接着又返回到activity A,这种情况下activity A一般不会因为内存的原因被系统销毁,故activity A的onRestoreInstanceState方法不会被执行。
另外,onRestoreInstanceState
的bundle
参数也会传递到onCreate
方法中,你也可以选择在onCreate
方法中做数据还原。 还有onRestoreInstanceState
在onstart之后执行。
场景实例:
打开activity关闭activity生命周期如下:
onCreate
>>>onStart
>>> onResume
>>> onPause
>>> onStop
>>> onDestroy
在activityA中打开Dialog样式的ActivityB,再关闭activityB时,activityA的生命周期如下:
onPause
>>> onSaveInstanceState
>>> onResume
屏幕旋转activity生命周期如下:
onPause
>>> onSaveInstanceState
>>> onStop
>>> onDestroy
>>> onCreate
>>> onStart
>>> onRestoreInstanceState
>>> onResume
按Home键后再开启app生命周期如下:
onPause
>>> onSaveInstanceState
>>> onStop
>>> onRestart
>>> onStart
>>> onResume
如何判断应用被强杀
在Application
中定义一个static常量,赋值为-1,在欢迎界面改为0,如果被强杀,application
重新初始化,在父类Activity判断该常量的值