开发艺术之旅 | Activity 生命周期和启动模式

生命周期

生命周期 状态 工作
onCreate Activity正在被创建 可以做一些初始化工作
onRestart Activity从不可见重新变成可见
onStart Activity正在被启动,“可见”但不在前台
onResume Activity可见并且出现在前台,可交互
onPause Activity正在停止,接下来一般会调用onStop 存储工作、停止动画,非耗时操作
onStop Activity即将停止 稍微重量级的回收操作,不能太耗时
onDestroy 即将被销毁 回收对象,释放资源

几种情况

  • 打开新的Activity或者回到桌面 onPause -> onStop
  • 回到原Activity onRestart -> onStart -> onResume
  • 按back键回退 onPause -> onStop -> onDestroy
  • 打开新的活动:旧的活动先执行 onPause方法,新的活动才会启动,执行顺序:onPause -> onCreate -> onStart -> onResume -> (First Activity) onStop 所以不能再onPause执行耗时操作,需要让新的Activity尽快显示出来

成对的生命周期

  • 从整个生命周期来看:onCreate 和 onDestroy 标注Activity的创建和销毁
  • 从Activity是否可见来看:onStart 和 onStop 可能会被调用多次
  • 从Activity是否在前台:onResume 和 onPause

onStart和onResume、onPause 和 onStop 的区别

角度不同 如上;实际使用无明显区别

异常情况下生命周期分析

  • onSaveInstanceState() :存储数据 在 onStop 方法之前调用
  • onRestoreInstanceState() :恢复数据 在onStart 方法之后调用

情况一:资源相关的系统配置发生改变

默认情况下Activity会被销毁并重新创建
onSaveInstanceState -> onDestroy/onCreate(new) -> onRestoreInstanceState

系统帮我们做了一定的恢复工作,例如文本框输入的数据、滑动位置等和View相关的状态

  • onRestoreInstanceState:Activity被销毁并且重新创建才会调用 里面的Bundle一定不为空

委托思想
每个view都有上述两个方法

  1. Activity -> onSaveInstanceState 保存数据
  2. Activity 委托 Window保存数据
  3. Window 委屈上面的顶级容器保存数据(Viewgroup,一般来说是DecorView)
  4. 顶层容器一一通知它的子元素保存数据

情况二:资源内存不足导致低优先级的Activity被杀死

优先级:

  1. 前台Activity
  2. 可见但非前台的Activity——例如打开了一个Dialog
  3. 后台Activity——已经被暂停的Activity,执行力onStop

如何在系统配置改变时不重新创建Activity?

AndroidMainifest中,activity标签有个字段:configChanges 可以定义,指定多个标签用“|”连接。

常用标签:
  • locale: 设备的本地位置发生了改变,一般为切换了系统语言
  • orientation: 屏幕方向发生了改变
  • keyboardHidden: 键盘的可访问性发生了改变,例如用户调出了键盘
需要注意的标签:
  • screenSize: 屏幕的尺寸信息发生了改变
  • smallestScreenSize: 设备的物理尺寸发生改变,例如切换了外部显示设备

当这两个标签在API小于13时,此选项不会导致Activity重启,否则会;因此在常用防止Activity进行重启需加入:

android:configChanges="orientation|screenSize"

加入后改变屏幕的方向就不会Activity就不会重启了

Activity的启动模式

  • standard
  • singleTop
  • singleTask
  • singleInstance

standard

标准模式,每次都会创建一个新的实例,并进入启动它的Activity的栈中;如果是由非Activity的context启动的(例如ApplicationContext),其并没有任务栈,因此会报错误,所以需要加上FLAG_ACTIVITY_NEW_TASK标记位,此时Activity实际上是以singleTask模式启动的

singleTop

栈顶复用,如果已经处于任务栈的栈顶,就不会重新创建这个Activity,而是会回调onNewIntent()方法【不会调用onCreate、onStart方法】

singleTask

栈内复用
如果在目标任务栈中存在Activity的实例,则不会创建一个新的Activity,而是将这个实例移到栈顶并将上面所有的Activity出栈,并回调onNewIntent()方法【不会调用onCreate、onStart方法】;

  • 如果目标任务栈不存在(跨应用调用),会先创建目标栈
  • 在目标任务栈中寻找实例,如果不存在,则创建实例并压入栈中,如果存在,则调到栈顶

参考,官翻

singleInstance

单实例模式
具有singleTask所有的特性,但是只能位于一个单独的任务栈中,后续调用都会启动这个栈中实例,除非任务栈被销毁

Activity的Flag

可以通过设定Flag设定启动模式,常见的几个Flag:

  • FLAG_ACTIVITY_NEW_TASK 指定为singleTask模式
  • FLAG_ACTIVITY_CLEAR_TOP 清空同一个任务栈中所有的Activity,一般配合NEW_TASK 一起使用
  • FLAG_ACTIVITY_SINGLE_TOP 指定为single_top模式
  • FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS 不会出现在历史Activity的列表中

隐式启动Activity(IntentFilter)

隐式启动必须匹配过滤列表中所有的种类,一个Activity可以有多组IntentFilter

  • action 字符串,区分大小写,如果有多个,只要匹配其中一个就可以
  • category 字符串,可以不指定,但是指定了就必须能匹配到,才能启动
  • data 由 mimeType 和 URI组成;mimeType 指媒体类型(image/jpeg、audio/mpeg4-generic、video/*)匹配时通过intent.setDataAndType(Uri data, String type)方法对date进行设置。
发布了27 篇原创文章 · 获赞 6 · 访问量 1636

猜你喜欢

转载自blog.csdn.net/weixin_41802023/article/details/97614462