Android Activity生命周期

1.Activity
Activity由任务栈管理。启动一个新的Activity后,该Activity将被加入到任务栈栈顶,之前的Activity位于此Activity底部。

Acitivity一般有四种状态:
①运行状态: Activity位于栈顶,此时正好处于屏幕最前方。(可见可交互)
②暂停状态:Activity失去了焦点,但仍然对用户可见(如栈顶的Activity是透明的或栈顶Activity并不是铺满整个手机屏幕)。可以在极低内存情况下被系统杀死。(可见不可交互)
③停止状态:当Activity被其他Activity完全遮挡,此时此Activity对用户不可见。它仍然保留所有状态和成员信息,但是它不再对用户可见,因此其窗口被隐藏,并且当其他地方需要内存时,它通常会被系统杀死。(不可见,不可交互)
④销毁状态:如果Activity在栈区中被移除后,当它再次显示给用户时必须完全重新启动并恢复到之前的状态。
在每个不同的状态阶段,Android系统会对Activity内相应的方法进行回调。因此写Activity时一般都是继承Activity类并重写相应的回调方法。

2.Activity生命周期
在这里插入图片描述
①onCreate()
Activity第一次被创建的时候调用。
在这个方法中完成activity的初始化操作,比如加载布局、绑定事件等以及第三方sdk的注册等。
②onStart()
Activity由不可见变为可见的时候调用。此时activity是用户可见状态,但没有焦点,不能与用户交互。
一般可在onStart()做一些动画的初始化操作。
③onResume()
Activity准备好和用户进行交互的时候调用。
此时Activity一定位于任务栈的栈顶,并且处于运行状态,可与用户进行交互。
④onPause()
系统准备去启动或恢复另一个Activity的时候调用。
通常会在这个方法中将一些极其消耗CPU的资源释放掉(比如显示地图或大规模图形)以及保存一些关键数据(比如用户输入的数据等)。
这个方法的执行速度一定要快,不然会影响到新的栈顶activity的使用。
当另外一个activity覆盖当前acitivty时,当前activity会进入到onPause()方法中,当前activity是可见的,但不能与用户交互状态。
⑤onStop()
Activity完全不可见的时候调用。此时activity对用户是不可见的。
在系统内存紧张的情况下有可能会被系统进行回收,所以一般在当前方法可做资源回收。
onStop()和onPause()方法的主要区别在于,如果启动的新Activity是一个对话框式的活动,那onPause()方法会得到执行,而onStop()方法并不会执行。
⑥onDestroy()
Activity被销毁之前调用,之后Activity的状态将变为销毁状态。
⑦onRestart()
Activity由停止状态变为运行状态的时候调用,也就是activity被重新启动了。
比如在用户按下home()之后,再次进入到当前activity时会调用onRestart()方法。调用顺序onPause()->onStop()->onRestart()->onStart()->onResume()。

注意:
①Activity实例是由系统自动创建的,并在不同的状态期间回调相应的方法。
一个最简单的完整Activity生命周期会按照如下顺序回调:onCreate -> onStart -> onResume -> onPause -> onStop -> onDestroy。
②当执行onStart方法时,Activity开始被用户所见。也就是说onCreate时用户是看不到此Activity的,此时用户看到的还是该Activity之前的那个Activity,从onStart一直到onStop之前,此阶段Activity都是被用户可见,称为visible lifetime。
③当执行到onResume回调方法时,Activity可以响应用户交互,一直到onPause方法之前,此阶段Activity称之为foreground lifetime。

举例说明:
假设A Activity位于栈顶,此时用户操作从A Activity跳转到B Activity,看看对于AB来说具体会回调哪些生命周期中的方法。
在这里插入图片描述
①开始时A被实例化,执行A:onCreate -> A:onStart -> A:onResume。
②当用户点击A中按钮启动B时,假设B全部遮挡住了A,将依次执行A:onPause -> B:onCreate -> B:onStart -> B:onResume -> A:onStop。
③此时如果点击Back键,将依次执行B:onPause -> A:onRestart -> A:onStart -> A:onResume -> B:onStop -> B:onDestroy。
④至此Activity栈中只有A。

注意:此时按下Back键和Home键对Activity A的生命周期影响不同:
①此时按下Back键,系统返回到桌面,并依次执行A:onPause -> A:onStop -> A:onDestroy。
②此时如果按下Home键,系统返回到桌面,并依次执行A:onPause -> A:onStop。因此Back键和Home键主要区别在于是否会执行onDestroy。

3.异常情况下activity的生命周期
情况一:资源相关的系统配置发生改变导致Activity被杀死并重新创建。
情况二:资源内存不足导致低优先级的Activity被杀死。
两种情况下Activity生命周期是相同的。

比如手机屏幕发生旋转时,由于系统配置发生改变,在默认情况下(即没有特殊设置)Activity会被销毁并重新创建。其生命周期如下:
在这里插入图片描述
与正常生命周期相比,多了数据的保存和恢复这两个过程。
当Activity在异常情况下终止时,系统会调用onSaveInstanceState方法将Activity的状态保存为一个Bundle对象,这个对象会在Activity重新创建后传递给onRestoreInstanceState()和onCreate(),这个方法的调用时机是在onStop之前,与onPause没有既定的时序关系。当Activity重新创建后系统会调用onRestoreInstanceState将onSaveInstanceState方法保存的Bundle对象作为参数,取出其中的数据进行恢复,这个方法的调用时机是在onStart之后。根据这一点可以判断onRestoreInstanceState方法是否被调用或者onCreate方法中的Bundle参数是否为null来确定Activity是否被重建。
每个View都有自己的onSaveInstanceState方法和onRestoreInstanceState方法,以根据不同View的需求来恢复不同的数据,例如TextView恢复了自身文本的选中状态和文本内容。

介绍一下onSaveInstanceState()和onRestoreInstanceState():
(1)onSaveInstanceState(Bundle outState):
该函数在Activity生命周期中执行。
①outState参数:
用于数据保存。Activity生命周期结束需要保存Activity状态的时候,会将要保存的数据以键值对的形式保存在Bundle对象中;
②该函数在Activity被销毁的时候调用,也可能没有销毁就调用了,比如:
按下Home键Activity进入了后台, 此时会调用该方法;
按下电源键屏幕关闭,Activity进入后台;
启动其它Activity,Activity被压入了任务栈的栈底;
横竖屏切换会销毁当前Activity并重新创建;
③onSaveInstanceState方法调用注意事项 :
a.用户主动销毁不会调用:当用户点击回退键或调用finish()方法时,不会调用该方法;
b.调用时机不固定:该方法一定是在onStop()方法之前调用,但是不确定是在onPause()方法之前 还是之后调用;
c.布局中组件状态存储:每个view组件都实现了 onSaveInstance()方法,在调用该函数的时候会自动保存组件的状态。注意,只有有id的组件才会保存;
d.关于默认的super.onSaveInstanceState(outState):该默认的方法是实现组件状态保存的;
(2)onRestoreInstanceState(Bundle outState):
①方法回调时机:在Activity被系统销毁之后恢复Activity时被调用。只有销毁了之后重建的时候才调用。如果内存充足,系统没有销毁这个 Activity,就不需要调用;
②Bundle对象传递 : 该方法保存的Bundle对象在Activity恢复的时候会通过参数传递到onCreate()方法中。

onSaveInstanceState方法保存的数据会传递给onRestoreInstanceState方法和onCreate方法。也就是说,进行数据恢复时有两种方式,一种是在onCreate方法中进行,一种是在onRestoreInstanceState方法中进行。
在onCreate方法中进行数据恢复的话需要考虑Activity是正常启动的还是被重建的,如果是正常启动那onCreate(Bundle onSaveInstanceState)中的onSaveInstanceState参数是null。官方文档是建议采用onRestoreInstanceState方法来恢复数据的。

异常情况下EditText数据恢复例子:
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.i(TAG, "onSaveInstanceState: ");
//存下自定义数据
outState.putString(“tom”,“异常下存数据 :tom”);
}

@Override
protected void onRestoreInstanceState( Bundle savedInstanceState) {
super.onRestoreInstanceState( savedInstanceState);
Log.i(TAG, "onRestoreInstanceState: ");
//读取存取的数据
Log.i(TAG, " " + savedInstanceState.get(“tom”));
}
在EditText中输入内容后旋转屏幕:
在这里插入图片描述
在这里插入图片描述
可以看到回调走了数据也恢复了。
注意:EditText控件一定要在xml布局中设置id,否则数据不会被恢复

4.activity优先级
Activity的优先级由高到低:
①前台Activity;
②可见但非后台Activity——例如被Dialog遮挡的的Activity;
③后台Activity——执行了onStop的Activity。

如果一个进程中没有四大组件在执行,那么这个进程将很快被杀死,因此一些后台工作最好是放在Service中从而提高优先级,不至于轻易被系统杀死。

Activity生命周期面试题:
①假设项目中有这样的需求,当指定的Activity在用户可见后才进行广播注册,在用户不可见后对广播进行注销,那应该在哪两个回调中做这个处理呢?
问题中强调了可见和不可见,所以只需要注重可见生命周期。在Activity启动后会先调用onCreat()方法进行布局和相关事件的绑定,直到回调onStart()方法后活动才可见,所以直接回答onStart()和onStop()即可。

②如果有一些数据在Activity跳转时(或者离开时)要保存到数据库,那么你认为是在onPause()好还是在onStop()执行这个操作好呢?
熟悉Activity生命周期的都知道,onPause()相比onStop()更容易触发。而「数据」就是APP甚至互联网产品的根,虽然绝大多数情况下都会遵从onPause() => onStop()的原则,但难以保证每次运行都能正常运行到onStop()方法,比如还没运行到onStop()系统就被回收了,所以最好在onPause中执行。
注意,这个操作要尽量地快,不然会影响到下一个Activity的生命周期。

③Activity A启动了Activity B,简单说下它们分别的生命周期的变化。

④Activity A通过Intent显示启动了Activity B,当B处于可见状态后,A是否一定会调用onStop()?
第三个和第四个问题考察的点基本一致,大概就想考察面试者是否认为只要最上层栈顶的Activity B处于可见状态,那下面一层的Activity A就一定会调用onStop()方法。答案是并不是一定会调用。Activity调用onStop()的时期是该Activity处于完全不可见状态,所以只需要想办法举出还可见的状态就好了。假设弹出一个对话框形式的 Activity B,甚至就算弹出一个正常的Activity B,把B的页面设置较低的透明度,实际上是一样的效果。

  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值