前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深入学习Activity的生命周期和启动模式

深入学习Activity的生命周期和启动模式

作者头像
trampcr
发布2018-09-28 15:49:26
6890
发布2018-09-28 15:49:26
举报
文章被收录于专栏:7号代码7号代码

《Android开发艺术探索》读书笔记之Activity的生命周期和启动模式

目录:

Activity的生命周期

  • 典型情况下的生命周期
  • 异常情况下的生命周期

Activity的启动模式

  • 用ApplicationContext启动standard模式的Activity
  • SingleTask模式中的参数TaskAffinity
  • 任务栈
  • 查看Activity 堆栈情况的命令
  • Activity指定启动模式的方式
  • Activity的Flags

一. Activity的生命周期

说到Activity的生命周期,相信很多人都熟悉,但是深入了解后,发现还是有很多需要注意的细节。这里将生命周期分为两种情况,一种是典型情况下的生命周期,一种是异常情况下的生命周期。

1.典型情况下生命周期

onStart():Activity已经可见了,但是还没有出现在前台,无法和用户进行交互。 onStart、onStop和onResume、onPause的区别: onStart、onStop是从Activity是否可见来回调的,而onResume、onPause是从Activity是否位于前台来回调的。

2.异常情况下生命周期

(1)资源相关的系统配置发生改变导致Activity被杀死并重新创建

例如:默认情况下,横竖屏的切换会导致Activity被销毁并重新创建,生命周期为onCreate -> onStart -> onResume -> onSaveInstanceState(和onPause没有确定的时序关系) -> onStop -> onDestroy -> onCreate -> onStart -> onRestoreInstanceState -> onResume。

关于保存和恢复View层次结构,系统的工作流程是:首先,Activity被意外终止时,Activity会调用onSaveInstanceState保存数据,然后,Activity会委托Window保存数据,接着Window再委托它上面的顶级容器(是一个ViewGroup,一般是一个DecorView)保存数据,最后,顶级容器再一一通知子元素保存数据,整个数据保存过程就完成了。

可以看到Activity中的onCreate和onRestoreInstanceState中都有Bundle savedInstanceState参数,说明可以在这两个方法中都可以恢复数据,但这两者是有区别的,它们的区别是:onRestoreInstanceState一旦被调用,其参数savedInstanceState一定有值,不需要进行额外的判断;但是onCreate不行,如果是正常启动的话,onCreate中savedInstanceState为null,所以必须额外判断。

如果不希望在横竖屏切换时重新创建Activity,可以给Activity指定configChanges属性。

常用的属性值有:

  • locale:设备的本地位置发生了改变,一般指切换了系统语言。
  • orientation:屏幕方向发生了变化。
  • keyboardHidden:键盘的可访问性发生了变化,比如用户调出了键盘。
  • screenSize:屏幕尺寸发生了改变。当屏幕尺寸发生变化,且minSDKVersion和targetSDKVersion至少有一个大于13,需要设置这个属性值保证Activity不被重新创建。

设置了Activity的属性configChanges,屏幕切换时如果Activity没有重新创建,则不会调用onSavedInstanceState和onRestoreInstanceState方法,而是会调用onConfigurationChanged方法,通过它的参数newConfig.orientation可以获取屏幕的方向代号。

(2)资源内存不足导致低优先级的Activity被杀死

Activity按照优先级从高到低依次为:

  • 前台Activity
  • 可见但非前台Activity
  • 后台Activity

当系统内存不足时,系统会按照Activity优先级去杀死Activity所在的进程。这种情况和情况一同样用onSaveInstanceState和onRestoreInstanceState来保存和恢复数据。

二. Activity的启动模式

Activity的四种启动模式就不一一阐述了,从问题入手来深入了解启动模式。

1. 用ApplicationContext启动standard模式的Activity

当我们用ApplicationContext启动standard模式的Activity的时候会报错,错误为:

代码语言:javascript
复制
android.util.AndroidRuntimeException:Calling startActivity from outside of an Activity context requires the
FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?

这是因为standard模式的Activity默认会进入启动它的Activity所属的任务栈中,但由于非Activity类型的Context并没有所谓的任务栈,所以会报这个错误。

解决方法:为待启动的Activity指定FLAG_ACTIVITY_NEW_TASK标记位,这样在启动时就会为它创建一个新的任务栈,这时启动Activity实际上是以singleTask模式启动的。

2. SingleTask模式中的参数TaskAffinity

TaskAffinity属性主要和singleTask启动模式或者allowTaskReparenting属性配对使用,在其他情况下没有意义,TaskAffinity意思是任务相关性,这个参数标识了一个Activity所需要的任务栈的名字,默认情况下,所有Activity所需的任务栈的名字为应用的包名。

当TaskAffinity和allowTaskReparenting结合使用的时候,当一个应用A启动了应用B的某个非MainActivity得Activity后,如果B这个Activity的allowTaskReparenting属性为true,那么当应用B被启动后,此Activity会直接从应用A的任务栈转移到应用B的任务栈中。

3. 任务栈

分为前台任务栈和后台任务栈,后台任务栈中的Activity处于暂停状态,用户可以通过切换将后台任务栈再次调到前台。

4. 查看Activity 堆栈情况的命令:adb shell dumpsys activity
  • adb shell dumpsys activity--------查看ActvityManagerService 所有信息
  • adb shell dumpsys activity activities-------查看Activity组件信息
  • adb shell dumpsys activity services---------查看Service组件信息
  • adb shell dumpsys activity providers------查看ContentProvider组件信息
  • adb shell dumpsys activity broadcasts-------查看BraodcastReceiver信息
  • adb shell dumpsys activity intents--------------查看Intent信息
  • adb shell dumpsys activity processes---------查看进程信息

通过看任务栈信息理解了《当前Activity》中第一行代表的正是任务栈,第二行代表当前类的全路径。

5. Activity指定启动模式的方式
  • 通过AndroidManifest为Activity指定启动模式属性launchMode。这种方式无法直接为Activity设定FLAG_ACTIVITY_CLEAR_TOP标识。
  • 通过Intent中设置标志位:intent.addFlags()。优先级高于第一种,这种方式无法为Activity指定singleInstance模式。
6. Activity的Flags

标记位的作用很多,有的可以设定Activity的启动模式,有的可以影响Activity的运行状态。

  • FLAG_ACTIVITY_NEW_TASK:作用是为Activity指定singleTask启动模式。
  • FLAG_ACTIVITY_SINGLE_TOP:作用是为Activity指定singleTop启动模式。
  • FLAG_ACTIVITY_CLEAR_TOP:singleTask启动模式默认就具有此标记位的效果。
  • FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS:具有此标记的Activity不会出现在历史Activity的列表中,等同于Activity的属性android:excludeFromRecents=”true”。

历史Activity列表是什么?

如果调出的Activity只是一个功能片段,并没有实际的意义,也没有必要出现在长按Home键调出最近使用过的程序类表中,那么使用FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS,所以历史 Activity列表可以理解为一个Activity栈,如果设置这个属性后,该Activity不会被保存在这个栈当中。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017.01.15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一. Activity的生命周期
  • 二. Activity的启动模式
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档