回调方法
方法 | 描述 | 常用情景 |
---|---|---|
onCreate() | 当活动第一次创建时调用 | 初始化数据,加载布局,绑定事件等 |
onStart() | 活动被启动时调用 | 略 |
onRestart() | 活动停止后被重启时调用 | 略 |
onResume() | 活动用户可见时,即开始与用户交互时调用,此时活动必位于栈顶 | 略 |
onPause() | 启动或者恢复另外一个活动时调用 | 信息持久化存储操作,停止消耗CPU资源等执行熟读要快,否则影响下一活动使用 |
onStop() | 活动完全不可见时调用 | 因为活动界面会被覆盖或销毁,所有要储存重要信息 |
onDestory() | 活动被销毁即出栈时被调用 | 数据回收,资源释放等 |
onSaveInstanceState() | 活动被异常停止,可以用Bundle保存数据,可以在活动再次创建时的onCreate()方法中使用保存下来的数据 | 防止活动异常停止导致的数据丢失 |
与用户交互(前台)时期:onResume() -> onPause()
可见到不可见时期(对应用而言):onStart() -> onStop()
启动到销毁时期:onCreat() -> onDestory()
Activity的启动方式
首先要知道的是活动的管理用的是Task,Task是返回栈。
当活动创建时压栈,活动被销毁时出栈。活动的启动方式一共有四种。standard
这种模式是活动默认的启动方式。特点:每创建一个活动,则一个活动压栈,不管栈中是否已经存在该活动的实例。singleTop
这种模式呢不会重复创建栈顶的活动,就是说当新创建的活动与栈顶的活动一样时不会重复创建,而是直接调用栈顶的活动。singleTask
这种模式可以让整个程序上下文只存在一个实例,就是说,创建新的实例前会判断栈中是否已经存在相同的实例,倘若已经存在,则不会新创实例。singlelnstance
指定这种模式的活动,会启动一个新的返回栈来管理该活动。无论哪个程序访问该活动都共用同一个返回栈
那个怎么指定一个活动的启动方式呢
在AndroidManifest.xml中的activity标签中指定,例如:
1 | <activity android:name=".MainActivity" |
举例
启动活动1
1
2
3活动1执行了: onCreate()
活动1执行了: onStart()
活动1执行了: onResume()活动1跳转活动2
1
2
3
4
5
6活动1执行了: onPause()
活动2执行了: onCreate()
活动2执行了: onStart()
活动2执行了: onResume()
活动1执行了: onStop()
活动1执行了: onSaveInstanceState(Bundle outState)活动2点击back返回活动1
1
2
3
4
5
6活动2执行了: onPause()
活动1执行了: onRestart()
活动1执行了: onStart()
活动1执行了: onResume()
活动2执行了: onStop()
活动2执行了: onDestroy()1、可见活动不可见了暂时不会被销毁,但是点击back会。
2、从活动1启动活动2,活动1的 onSaveInstanceState() 会被执行;但是按back键返回活动1,活动2的 onSaveInstanceState() 并不会执行,即使活动2已经被销毁。
3、从活动1启动活动2,先执行活动1的 onPause() 然后创建活动2,再执行活动1的 onStop()**,因此 **onPause() 的操作不宜过于耗时,否则影响活动2的启动。熄屏
1
2
3活动1执行了: onPause()
活动1执行了: onStop()
活动1执行了: onSaveInstanceState(Bundle outState)再亮屏
1
2
3活动1执行了: onRestart()
活动1执行了: onStart()
活动1执行了: onResume()点击home键
1
2
3活动1执行了: onPause()
活动1执行了: onStop()
活动1执行了: onSaveInstanceState(Bundle outState)再打开app
1
2
3活动1执行了: onRestart()
活动1执行了: onStart()
活动1执行了: onResume()熄屏和返回home,都不会销毁该活动,再次打开app会被重启,执行 onRestart() 方法。
竖屏旋转为横屏 或者 横屏转竖屏
1
2
3
4
5
6
7活动1执行了: onPause()
活动1执行了: onStop()
活动1执行了: onSaveInstanceState(Bundle outState)
活动1执行了: onDestroy()
活动1执行了: onCreate()
活动1执行了: onStart()
活动1执行了: onResume()屏幕方向的改变,会销毁当前活动,并且新创建一个新的活动。
横屏状态下熄屏再亮屏 或者 横屏状态点击home键再点开app
1
2
3
4
5
6
7活动1执行了: onPause()
活动1执行了: onStop()
活动1执行了: onSaveInstanceState(Bundle outState)
活动1执行了: onDestroy()
活动1执行了: onCreate()
活动1执行了: onStart()
活动1执行了: onResume()横屏状态下熄屏或者横屏状态点击home键,都会销毁当前活动,再次打开时新创建一个活动,此时屏幕也变成了竖屏状态。
补充:默认情况下,系统配置发生改变时,如屏幕旋转,Activity是会被重新创建的,当然你想要不重建Activity也行,AndroidManifest的Activity标签下有一个属性android:configChanges,该属性指定的系统配置即使改变了,Activity也不会被销毁重建。如,我不希望屏幕方向改变而重新创建活动则:
1 | <activity android:name=".MainActivity" |
该属性常用的值有:
1、orientation:屏幕方向发生改变
2、locale:设备的本地位置发生了改变,一般指切换了系统语言;
3、keyboardHidden:键盘的可访问性发生了改变,例如用户调出了键盘。
最后说一下onSaveInstanceState()这个正常finifh一个活动方法不会被执行的,其它情况
停止一个活动则会执行。我的理解,onSaveInstanceState()是防止某些数据在Activity停
止时丢失的(用Bundle存起来),如果该活动还有可能被重启或重新创建则会执行onSaveIn
stanceState(),以便恢复上回的数据,但是正常finish一个活动,说明该活动已经正
常结束了,我不会再用它了,则不会执行onSaveInstanceState()。
其实有兴趣还可以对Activity整个周期的的实现源码看一遍,这里不多说了,从https://www.jianshu.com/p/ee6a0e45bbec可知一下几点:
- activity的生命周期是通过handler消息来控制的;
- activity的实例创建是通过反射来实现的;
- 在activity onResume生命周期后,才将布局view绘制添加到系统布局中并显示给用户;
- 在activity onDestory生命周期后,只是将window中的view,DecorView移除并置为null,并没有将activity实例置为null,activity实例仍然在内存中,如果在gc时还有持有该activity的引用就会造成内存泄露,也就是说activity onDestory后只是页面的销毁,并不代表当前activity实例的销毁。
参考资料
- 《第一行代码》
- 博客https://www.jianshu.com/p/b5a72a741025
- 博客https://www.jianshu.com/p/ec50675ed116
如有错误,恳请指正。