1.Activity
Activity由Activity栈管理。启动一个新的Activity后,此Activity将被加入到Activity栈顶,之前的Activity位于此Activity底部。
Acitivity一般有四种状态:
①运行状态: Activity位于栈顶,此时正好处于屏幕最前方。(可见可交互)
②暂停状态:Activity失去了焦点,但仍然对用户可见(如栈顶的Activity是透明的或者栈顶Activity并不是铺满整个手机屏幕)。可以在极低内存情况下被系统杀死。(可见不可交互)
③停止状态:当Activity被其他Activity完全遮挡,此时此Activity对用户不可见。它仍然保留所有状态和成员信息,但是它不再对用户可见,因此其窗口被隐藏,并且当其他地方需要内存时,它通常会被系统杀死。(不可见,不可交互)
④销毁状态:Activity在栈区中被移除的时候,当它再次显示给用户时,必须完全重新启动并恢复到之前的状态。
在每个不同的状态阶段,Android系统会对Activity内相应的方法进行回调。因此,写Activity时一般都是继承Activity类并重写相应的回调方法。
2.Activity生命周期
先看官方给的图:
①onCreate():
在Activity第一次被创建的时候调用。在这个方法中完成活动的初始化操作,比如加载布局、绑定事件等以及第三方sdk的注册等。
②onStart():
在Activity由不可见变为可见的时候调用。此时activity是用户可见状态,但没有焦点,不能与用户交互,一般可在onStart()做一些动画的初始化操作。
③onResume():
在Activity准备好和用户进行交互的时候调用。 此时Activity一定位于返回栈的栈顶,并且处于运行状态,可与用户进行交互。
④onPause():
在系统准备去启动或者恢复另一个Activity的时候调用。通常会在这个方法中将一些极其消耗CPU的资源释放掉(比如显示地图或者大规模图形),以及保存一些关键数据(比如用户输入的数据等),但这个方法的执行速度一定要快,不然会影响到新的栈顶活动的使用。
当另外一个activity覆盖当前acitivty时,当前activity会进入到onPause()方法中,当前activity是可见的,但不能与用户交互状态。
⑤onStop():
在Activity完全不可见的时候调用。此时activity对用户是不可见的。在系统内存紧张的情况下有可能会被系统进行回收,所以一般在当前方法可做资源回收。
onStop()和onPause()方法的主要区别在于,如果启动的新Activity是一个对话框式的活动,那onPause() 方法会得到执行,而onStop()方法并不会执行。
⑥onDestroy():
在Activity被销毁之前调用,之后Activity的状态将变为销毁状态。
⑦onRestart():
在Activity由停止状态变为运行状态之前调用,也就是活动被重新启动了。比如在用户按下home()之后,再次进入到当前activity的时候会调用onRestart()方法。调用顺序onPause()->onStop()->onRestart()->onStart()->onResume()。
需要注意:
①Activity实例是由系统自动创建,并在不同的状态期间回调相应的方法。
一个最简单的完整的Activity生命周期会按照如下顺序回调:onCreate -> onStart -> onResume -> onPause -> onStop -> onDestroy。称为entire lifetime。
②当执行onStart回调方法时,Activity开始被用户所见(也就是说,onCreate时用户是看不到此Activity的,那用户看到的是哪个?当然是此Activity之前的那个Activity),一直到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。
在Android中,有两个按键在影响Activity生命周期这块需要格外区分下,即Back键和Home键。先直接看下实验结果:
①此时如果按下Back键,系统返回到桌面,并依次执行A:onPause -> A:onStop -> A:onDestroy。
②此时如果按下Home键,系统返回到桌面,并依次执行A:onPause -> A:onStop。因此,Back键和Home键主要区别在于是否会执行onDestroy。
3.异常情况下activity的生命周期
根据手机使用过程中的常见情形,从两种情况来讨论Activity在异常模式下的生命周期:
情况1:资源相关的系统配置发生改变导致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):
onSaveInstanceState函数在Activity生命周期中执行。
①outState参数作用 :
数据保存 。Activity生命周期结束需要保存Activity状态的时候,会将要保存的数据以键值对的形式 保存在Bundle对象中;
②调用时机 :
Activity被销毁的时候调用,也可能没有销毁就调用了:
按下Home键Activity进入了后台, 此时会调用该方法;
按下电源键屏幕关闭,Activity进入后台;
启动其它Activity,Activity被压入了任务栈的栈底;
横竖屏切换会销毁当前Activity并重新创建;
③onSaveInstanceState方法调用注意事项 :
a.用户主动销毁不会调用 : 当用户点击回退键或者 调用了finish()方法,不会调用该方法;
b.调用时机不固定 : 该方法一定是在onStop()方法之前调用,但是不确定是在onPause()方法之前 还是之后调用;
c.布局中组件状态存储 : 每个组件都实现了 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方法来恢复数据的。
情况2:资源内存不足导致低优先级的Activity被杀死
这种情况不方便模拟,但生命周期和情况1是相同的。
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的页面设置较低的透明度,实际上是一样的效果。
今天的文章Android Activity生命周期★分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/12837.html