问题一、activity的声明周期是怎么样的?
这是google官网提供的activity生命周期图
问题二、看到这张图,我回想起以下几点。
- 当一个activity被设置为lancher的时候,系统会调用activity的onCreate()。
- 当调用startactivity的时候,系统调用onCreate()。
- 当调用finish或者是按返回键的时候,系统调用onDestory()。
- 正常情况下
- 考虑到activity会因为android系统内存不足的时候,会被系统回收资源。
- 内存系统充足,但是设备配置的改变(比如说:屏幕旋转)。
1、先说正常情况下的情况:
- 没有调用finish()的情况:
分析上面打印出来的结果:
- activity1启动的时候,调用oncreate()-------->onStart()-------->onResume()
- 点击跳转的时候,调用(activity1)onSaveInstanceState()--------->(activity1)onPause()---------->(activity2)onCreate()---->(activity2)onStart()------->(activity2)onResume()-------->(activity1)onStop()
- 点击返回按钮(调用finish())或者是返回键,(activity2)onPause()-------->(activity1)onRestart()-------->(activity1)onStart()---------->(activity1)onResume()--------->(activity2)onStop()-------->(activity1)onDestory()
2、有finish()的情况
- activity1启动的时候,调用oncreate()-------->onStart()-------->onResume()
- 点击跳转的时候,调用(activity1)onPause()---------->(activity2)onCreate()---->(activity2)onStart()------->(activity2)onResume()-------->(activity1)onStop()----->(activity1)onDestory()
- 点击返回按钮(调用finish())或者是返回键,(activity2)onPause()-------->(activity2)onStop()-------->(activity2)onDestory()
- 在跳转到其他activity之前,当前activity的onPause函数会被调用,接着是目标activity会调用其activity的生命周期的函数,当这个目标activity可见的时候,之前的activity才会调用onstop()
- 返回的时候,activity2会先onPause(),然后调用activity1的(activity1)onRestart()-------->(activity1)onStart()---------->(activity1)onResume()--------->(activity2)onStop()-------->(activity1)onDestory()
- 没有调用finish()就跳转到其他的activity,系统会调用onSaveInstanceState()来保存当前activity的状态。
- 调用了finished()后再跳转到其他的activity,系统就不会调用onSaveInstanceState()
如果过没有调用finish()或者是按返回键,就表示这个activity没有结束,或者说这个activity不想被结束,是想被保留下来,以后有用,但是在系统运行的过程中,这个activity有可能被destory掉,如果这个事情真的发生了,那么当用户再返回到这个activity的时候,系统会重新创建一个新的activity,调用oncreate()-------->onStart()-------->onResume(),这个时候用户看到的就不是先前的那个activity的状态了(比如说:网络请求过来的数据;在edittext里面填写的账户)。这种情况对于用户来说简直是不可接受的,大大降低了用户体验。为了解决的问题,请继续往下看。。。
2、考虑到activity会因为android系统内存不足的时候,会被系统回收资源。
基于上面提出的问题,根据google官网提供的文档以及相关实验得知:我们的android系统工程师就想了一个办法,对于你不想destroy的activity,我们就用一个函数(onSaveInstanceState())来保存当前activity的状态(比如说:edittext里面的账户),有了备份状态,当用户返回的时候,情况一、如果这个activity没有被系统destroy掉,那么我们就调用onRestart()--------........恢复到先前的状态(为什么能够回复?google官网说:这个时候,这个activity的状态都在内存中,用户返回的时候,系统只是把数据取出来显示就可以了);情况二、如果这个activity被系统destroy掉了,这个时候系统就得创建一个新的activity,这个时候就会调用oncreate()-------->onStart()-------->onResume(),这个时候我们就把之前存储的activity状态取出来,然后回复到以前activity的状态,这些状态是存在bundle里面的。恢复状态,我们可以重写onCreate()或者是onRestoreInstanceState(),详情点击这里
3、内存系统充足,但是设备配置的改变(比如说:屏幕旋转)
android系统还真是考虑得周全,但是考虑周全的同时,也会增加开发的难度。以下是屏幕旋转以后的程序执行的结果
当屏幕旋转的时候,activity1的生命周期函数调用为:onPause()------>onSaveInstanceState()------>onStop()------->onRetanNonConfigurationInstance()------>onDestory()......................这里是这个activity的结束,因为没有主动调用finish(),所以会调用onSaveInstanceState()把数据保存下来(所以这里也符合1这一点的情况),因为屏幕旋转了,所以activity会调用onCreate()(调用getLastNonConfigurationInstance())------>onRestoreInstanceState()-------->onStart()---------------->onResume()创建了新的activity。
总结:
1、正常情况:
- 有finish()情况:不会调用onSaveInstanceState(),因为没有屏幕旋转,当然不会调用onRetanNonConfigurationInstance()
- 没有finish()的情况,会调用onSaveInstanceState()来保存状态,因为没有屏幕旋转,当然不会调用onRetanNonConfigurationInstance()
- 因为前面调用了onSaveInstanceState()来保存状态,返回的时候这个activity被destroy掉了,所以系统会重新new一个新的activity,这个时候系统会调用onRestoreInstanceState()来回复activity的状态,因为没有屏幕旋转,当然不会调用onRetanNonConfigurationInstance()
- 先会调用onSaveInstanceState()来保存状态,因为屏幕旋转了,会调用onRetanNonConfigurationInstance(),接着会重新new一个新的activity,可以在onCreate里面来调用getLastNonConfigurationInstance()来恢复到屏幕旋转前的状态,如果把状态保存在bundle里面,也可以用bundle来恢复状态,这个时候就可以在onCreate()里面用bundle或者在onRestoreInstanceState()里面来恢复状态。