美文网首页
Activity的生命周期

Activity的生命周期

作者: JimmieYang | 来源:发表于2018-10-03 11:34 被阅读1437次

典型情况下的生命周期分析

Activity生命周期
  1. activity 第一次启动 : onCreate -> onStart -> onResume
  2. 用户打开新activity,原activity的过程 : onPause -> onStop.(如果新activity采用透明主题,当前activity不会调用onStop)
  3. 再次回到原activity : onRestart -> onStart -> onResume
  4. 用户按回退键 : onPause -> onStop -> onDestory
  5. 屏幕息屏 :
  6. 屏幕亮屏 :
  7. onCreate,onDestory 表示一个activity的创建和销毁,一次生命周期过程中,只能调用一次.
  8. onStart,onStop 是从activity的是否可见
  9. onResume,onPause 是从activity是否位于前台来判断的

新页面启动时,旧Activity 调用 onPause后,新Activity才调用onResume.
onPause->新onCreate->新onStart->新onResume->旧onStop

因此,不能在 onPause中做耗时的操作.


异常情况下生命周期分析

activity异常中断生命周期

常见的两种情况下,导致Activity重建

  1. 资源相关的系统配置发生改变导致Activity被杀死后重建
  2. 资源内存不足导致优先级低的Activity被杀死

异常重建过程中,数据的保存和恢复

Activity被异常终止后,会调用 onSaveInstanceState方法, 改方法在 onStop之前调用,使用Bundle对象来保存数据.正常结束Activity生命周期的过程是不会调用 onSaveInstanceState方法.

Activity 重建后, 将调用 onRestoreInstanceState 用于恢复数据,销毁时保存的Bundle数据,将以回调参数的形式返回给onRestoreInstanceState,和onCreate方法.

正常启动时, onCreate中的Bundle为空,异常重建时不为空.
因此,在 onCreate中恢复数据,需要判断 Bundle数据是否为空,而onRestoreInstanceState只有异常重建时,才会被调用.
官方建议,在onRestoreInstanceState中恢复数据.

onSaveInstanceState,onRestoreInstanceState系统自动恢复某些数据

系统在Activity异常销毁过程中,会为我们保存当前Activity的视图结构,并在重建过程中恢复.
如 文本输入框的 输入数据, 列表滚动的位置, TextView中的选中状态和文本内容

Activity的优先级

  1. 前台Activity (正在和用户交互的Activity) 优先级最高
  2. 可见但非前台Activity (如被对话框挡住的Activity)
  3. 后台Activity (onStop) 优先级最低

当系统内存不足时, 按照上述优先级去杀死目标Activity所在的进程.

配置改变后,不销毁Activity

Android 配置文件中, 可以给Activity指定 configChanges 属性, 不让Activity销毁.

  • configChanges含义
说明
“mcc” IMSI 移动国家/地区代码 (MCC) 发生了变化 - 检测到了 SIM 并更新了 MCC。
“mnc” IMSI 移动网络代码 (MNC) 发生了变化 - 检测到了 SIM 并更新了 MNC。
“locale” 语言区域发生了变化 — 用户为文本选择了新的显示语言。
“touchscreen” 触摸屏发生了变化。(这种情况通常永远不会发生。)
“keyboard” 键盘类型发生了变化 — 例如,用户插入了一个外置键盘。
“keyboardHidden” 键盘无障碍功能发生了变化 — 例如,用户显示了硬件键盘。
“navigation” 导航类型(轨迹球/方向键)发生了变化。(这种情况通常永远不会发生。)
“screenLayout” 屏幕布局发生了变化 — 这可能是由激活了其他显示方式所致。
“fontScale” 字体缩放系数发生了变化 — 用户选择了新的全局字号。
“uiMode” 用户界面模式发生了变化 — 这可能是因用户将设备放入桌面/车载基座或夜间模式发生变化所致。 请参阅 UiModeManager。 此项为 API 级别 8 中新增配置。
“orientation” 屏幕方向发生了变化 — 用户旋转了设备。注:如果您的应用面向 API 级别 13 或更高级别(按照 minSdkVersion 和 targetSdkVersion 属性所声明的级别),则还应声明 "screenSize" 配置,因为当设备在横向与纵向之间切换时,该配置也会发生变化。
“screenSize” 当前可用屏幕尺寸发生了变化。它表示当前可用尺寸相对于当前纵横比的变化,因此会在用户在横向与纵向之间切换时发生变化。 不过,如果您的应用面向 API 级别 12 或更低级别,则 Activity 始终会自行处理此配置变更(即便是在 Android 3.2 或更高版本的设备上运行,此配置变更也不会重新启动 Activity)。此项为 API 级别 13 中新增配置。
“smallestScreenSize” 物理屏幕尺寸发生了变化。它表示与方向无关的尺寸变化,因此只有在实际物理屏幕尺寸发生变化(如切换到外部显示器)时才会变化。 对此配置的变更对应于smallestWidth 配置的变化。 不过,如果您的应用面向 API 级别 12 或更低级别,则 Activity 始终会自行处理此配置变更(即便是在 Android 3.2 或更高版本的设备上运行,此配置变更也不会重新启动 Activity)。此项为 API 级别 13 中新增配置。
“layoutDirection” 布局方向发生了变化。例如,从从左至右 (LTR) 更改为从右至左 (RTL)。 此项为 API 级别 17 中新增配置。

如要禁止屏幕翻转,导致Activity销毁,可做如下操作

<activity android:name=".MyActivity"
          android:configChanges="orientation|“screenSize”"
          android:label="@string/app_name">

如果屏幕发生旋转,Activity不会销毁,但是会回调 onConfigurationChanged方法.

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    // Checks the orientation of the screen
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
        Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
    }
}

参考

  1. Android开发艺术探索(任玉刚)
  2. Understand the Activity Lifecycle(android官方教程)

相关文章

网友评论

      本文标题:Activity的生命周期

      本文链接:https://www.haomeiwen.com/subject/gluzoftx.html