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的时候,系统会调用activity的oncreate()方法,在这个方法中我们会初始化当前布局setContentLayout()方法。 ②onStart(): onCreate()方法完成后,此时activity进入onStart()方法,当前activity是用户可见状态,但没有焦点,与用户不能交互,一般可在当前方法做一些动画的初始化操作。 ③onResume(): onStart()方法完成之后,此时activity进入onResume()方法中,当前activity状态属于运行状态 (Running),可与用户进行交互。 ④onPause() 当另外一个activity覆盖当前的acitivty时,此时当前activity会进入到onPause()方法中,当前activity是可见的,但不能与用户交互状态。 ⑤onStop() onPause()方法完成之后,此时activity进入onStop()方法,此时activity对用户是不可见的,在系统内存紧张的情况下,有可能会被系统进行回收。所以一般在当前方法可做资源回收。 ⑥onDestory() onStop()方法完成之后,此时activity进入到onDestory()方法中,结束当前activity。 ⑦onRestart() onRestart()方法在用户按下home()之后,再次进入到当前activity的时候调用。调用顺序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。
由于Android本身的特性,使得现在不少应用都没有直接退出应用程序的功能,按照一般的逻辑,当Activity栈中有且只有一个Activity时,当按下Back键,此Activity会执行onDestroy,那么下次点击此应用程图标将重新启动,因此,当前不少应用程序都是采取如Home键的效果,当点击了Back键,系统返回到桌面,然后点击应用程序图标,直接回到之前的Activity界面,这种效果是怎么实现的呢? 通过重写按下Back键的回调函数,转成Home键的效果即可。 @Override public void onBackPressed() { Intent home = new Intent(Intent.ACTION_MAIN); home.addCategory(Intent.CATEGORY_HOME); startActivity(home); } 这种方式通过Home键效果强行影响到Back键对Activity生命周期的影响。注意,此方法只是针对按Back键需要退回到桌面时的Activity且达到Home效果才重写。 或者,为达到此类效果,Activity实际上提供了直接的方法。 activity.moveTaskToBack(true); moveTaskToBack()方法直接将当前Activity所在的Task移到后台,同时保留activity顺序和状态。
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中从而提高优先级,不至于轻易被系统杀死。
|