博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Activity的生命周期和启动模式
阅读量:3957 次
发布时间:2019-05-24

本文共 4120 字,大约阅读时间需要 13 分钟。

Activity的生命周期和启动模式

前言

本文是《Android开发艺术探索》的笔记大纲,方便日后复习和记忆。

Activity典型情况下的生命周期

在这里插入图片描述

  1. onCreate:表示Activity正在被创建,这是生命周期的第一个方法。在这个方法中,我们可以做一些初始化工作,比如调用setContentView去加载界面布局资源、初始化Activity所需数据等。
  2. onRestart:表示Activity正在被重新启动。一般情况下,当当前Activity从不可见变为可见状态时,onRestart就会被调用。这种情形一般是用户行为所导致的,比如用户按Home键切换到桌面或者用户打开了一个新的Activity就会暂停,也就是onPause和onStop被执行了,接着用户又回到了这个Activity,就会出现这种情况。
  3. onStart:表示Activity正在被启动,即将开始,这是Activity已经可见了,但是还没有出现在前台,还无法和用户交互。这个时候其实可以理解为Activity已经显示出来了,但是我们还看不到。
  4. onResume:表示Activity已经可见了,并且出现在前台并开始活动。要注意这和onStart的对比,onStart和onResume都表示Activity已经可见,但是onStart的时候Activity还在后台,onResume的时候Activity才显示到前台。
  5. onPause:表示Activity正在停止,正常情况下,紧接着onStop就会被调用。在特殊情况下,如果这个时候快速地再回到当前Activity,那么onResume会被调用。onPause可以做一些存储数据,停止动画等工作,但是不能太耗时,因为这会影响新Activity的显示,onPause先执行完,新Activity的onResume才会执行。
  6. onStop:表示Activity即将停止,可以做一些稍微重量级的回收工作,同样不能太耗时。
  7. onDestroy:表示Activity即将被销毁,这是Activity生命周期中的最后一个回调,在这里,我们可以做一些回收工作和最终的资源释放。

onStart、onResume和onPause、onStop的区别

onStart和onStop是从Activity是否可见这个角度来回调的,而onResume和onPause是从Activity是否位于前台这个角度来回调的。

Activity A 打开 Activity B 生命周期回调

在这里插入图片描述

A onPause -> B onCreate -> B onStart -> B onResume -> A onStop
(注意:需要Activity A的onPause执行后,新的Activity才会开始创建)

Activity异常情况下的生命周期

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

当我们把一张图片放在drawable目录后,就可以通过Resources去获取这张图片。同时为了兼容不同的设备,我们可能还需要在其他一些目录放置不同的图片,比如drawable-mdpi、drawable-hdpi、drawable-land等。这样,当应用程序启动时,系统就会根据当前设备的情况去加载合适的Resouces资源,比如说横屏手机和竖屏手机会拿到2张不同的图片(设定了landscape或portrait状态下的图片)。比如当前Activiy处于竖屏状态,如果突然旋转屏幕,由于系统配置发生了改变,在默认情况下,Activity就会被销毁并且重新创建,当然我们也可以组织系统重新创建我们的Activity。

在默认情况下,如果我们的Activity不做特殊处理,那么当系统配置发生改变后,Activity就会被销毁并重新创建。

在这里插入图片描述
当系统配置发生改变后,Activity会被销毁,其onPause,onStop,onDestroy均会被调用。由于Activity是在异常情况下终止的:

  • 系统会调用onSaveInstanceState来保存当前Activity的状态,这个方法的调用时机是在onStop之前,它和onPause没有既定的时序关系。
  • 当Activity被重新创建后,系统会调用onRestoreInstanceState,并且把Activity销毁时onSaveInstanceState方法时所保存的Bundle对象作为参数同时传递给onRestoreInstanceState和onCreate方法,onRestoreInstanceState的调用时机在onStart之后。

在onSaveInstanceState和onRestoreInstanceState,系统自动为我们做了一定的恢复工作。当Activity在异常情况下创建时,系统会默认为我们保存当前Activity的视图结构,并且在Activity重启后为我们恢复这些数据,比如文本框中用户输入的数据、ListView滚动的位置,这些View相关的状态系统都能够默认为我们恢复。和Activity一样,每个View都有onSaveInstanceState和onRestoreInstanceState这两个方法

关于保存和恢复View层次结构,系统的工作流程如下:首先Activity被异常终止,Activity会调用onSaveInstanceState去保存数据,同时委托window去保存数据,window再委托它上面的顶层容器(很可能是DecorView)去保存数据,最后顶层容器再去一一通知它的子元素保存数据。(有点类似于事件分发)

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

数据存储和恢复过程和情况1完全一致

Activity按照优先级从高到低,可以分为如下三种:

  1. 前台Activity——正在和用户交互的Activity,优先级最高
  2. 可见但非前台Activity——比如Activity中弹出了一个对话框,导致Activity可见但是位于后台无法和用户直接交互。
  3. 后台Activity——已经被暂停的Activity,比如执行了onStop,优先级最低。

Activity的启动模式

Activity的LaunchMode

  1. standard:标准模式,这也是系统的默认模式。每次启动一个Activity都会重新创建一个实例。
  2. singleTop:栈顶复用模式。如果新的Activity已经位于任务栈的栈顶,那么此Activity不会被创建,同时它的onNewIntent将会被回调。如果新的Activity已存在但不位于栈顶,那么新的Activity仍然会被创建。
  3. singleTask:栈内复用模式。在这种模式下,只要Activity在一个栈中存在,那么多次启动此Activity都不会创建新的实例。和singleTop一样,系统会回调其onNewIntent方法。具体一点,当一个具有singleTask模式的Activity A请求启动后,系统首先会寻找是否存在其需要的任务栈,如果不存在该任务栈,则创建该任务栈并且创建Activity A将其压入栈中。如果存在该任务栈,则检查栈中是否存在Activity A,如果存在,将Activity A调至栈顶,并回调其onNewIntent方法,如果不存在,则创建Activity A并将其压入栈中。
  4. singleInstance:单实例模式。这是一种加强的singleTask模式,它除了具有singleTask的所有特性外,还加强了一点,那就是具有此种模式的Activity只能单独地位于任务栈中。

指定Activity的启动模式的方法

第一种方法是在AndroidMenifest中指定启动模式,第二种方式是通过Intent中设置标志位来为Activity指定为启动模式。

2种方式的区别:第二种方式的优先级高于第一种,当两种同时存在时,以第二种方式为准。其次,这两种方式的限定范围上有所不同,第一种方法无法直接指定FLAG_ACTIVITY_CLEAR_TOP标识,而第二种方式无法为Activity指定singleInstance模式

IntentFilter的匹配规则

启动Activity分为2种:显式调用和隐式调用。显式调用的优先级高于隐式调用。隐式调用需要Intent能够匹配目标组件的IntentFilter中所设置的过滤信息,如果不匹配则无法启动Activity。

为了匹配过滤列表,需要同时匹配过滤列表中的action、category、data信息,否则匹配失败。

一个Activity可以有多个intent-filter,一个intent只要能匹配一组intent-filter即可成功启动对应的activity。

action的匹配规则

action的匹配要求intent中的action存在且必须和过滤规则中的其中一个相同。

category的匹配规则

  1. category的匹配要求intent中如果含有category,那么所有的category都必须和过滤规则中的其中一个category相同。
  2. intent中可以没有category,如果没有category,intent依旧可以匹配成功。
  3. 系统在用startActivity或者startActivityForResult的时候会默认为intent加上“android.intent.category.DEFAULT”。为了activity能够接收隐式调用,需要在intent-filter中添加“android.intent.category.DEFAULT”。

action和category的不同

action是必须有且和其中intent-filter中一个action相同。

category可以没有,但是如果有它必须和intent-filter中的一个相同。

data的匹配规则

如果过滤规则中定义了data,那么Intent中也要定义可匹配的data。

转载地址:http://vdtzi.baihongyu.com/

你可能感兴趣的文章
亲历惊心48小时,抢救35亿交易数据 [看一下数据管理的重要性]
查看>>
出国以后才知道英语应该怎么学
查看>>
金融危机下最抢手的八大IT专业人才
查看>>
计算机专业权威期刊投稿经验总结
查看>>
如何在三个月内学会一门外语?
查看>>
在struts1.x中设置对java.util.Date类型支持
查看>>
DWR可扩展无级级连下拉菜单的代码例子
查看>>
看看你对Linux到底了解多少?
查看>>
网上看到的:ARM入门最好的文章(转)
查看>>
中国最美情诗100句
查看>>
Javascript的IE和Firefox兼容性汇编
查看>>
javascript注册window的onload事件问题研究
查看>>
客户端技术分页控件javascript+css,可用于任何服务器端技术
查看>>
学习Swing 的网站[转]
查看>>
Google App engine 的第一个应用 midispot
查看>>
提问的智慧
查看>>
关于dom4j无法解析xmlns问题及生成非UTF-8字符集乱码问题的解决
查看>>
俞敏洪语录,你看后绝对有收获
查看>>
很好的一篇文章 如果让我重做一次研究生 王汎森
查看>>
保护U盘批处理文件
查看>>