赞
踩
Android Activity生命周期及启动模式详解
Activity生命生命周期
主要从两个方面来总结:
生命周期总览(自己画的图片,丑一些):
正常情况下的生命周期:
Activity的生命周期可以成对的来记忆:
1.onCreate和onDestory是一对,标识着Activity的创建与销毁
2.onStart和onStop是一对,标识着Activity的开始可见与不可见
3.onResume和onPause是一对,标识着Activity是否有焦点,也是能否与用户进行交互
Activity从启动到运行经过onCreate-->onStart()-->onResume,onCreate的时候不可见,到onStart的时候Activity已经是可见的了.
当Activity失去焦点但是仍然可见的时候会调用onPause(常见的情况是弹出Dialog或者透明背景的Activity) , 打开新的Activity或者回调桌面,Activity彻底不可见的时候回回调onStop,打开新Activity的流程如下:
锁屏与解锁触发的是onPause方法,没有onStop
当前Activity执行的是onPause-->onStop,要启动的Activity按正常的生命周期走,要注意的是只有当前Activity回调onPause结束之后才能启动另一个Activity,所以应该尽量避免在onPause内处理耗时任务
如果Activity从无焦点可见到有焦点可见(常见的情景是Dialog消失),回调onResume回到运行状态
Activity从完全不可见的状态回到可见状态(回到原Activity),调用的是onRestart-->onStart-->onResume.前提是在onStop之后未被系统回收,如果当前Activity优先级较低内存不足时被系统回收,那么退回Activity时会重新开始生命周期,即onCreate-->onStart-->onResume
从整个生命周期来说,onCreate和onDestory是相对的,标志着Activity的创建和销毁,onStart和onStop是相对的,标志着Activity是否可见,onResume和onPause是相对的,标志着Activity是否有焦点,或者理解为是否在前台
Activity的启动流程概述
异常情况下的生命周期:
所谓异常情况,就是除了受用户操作所导致的生命周期方法调度之外的其他情况,主要有两类:
资源文件相关的系统配置发生改变的情况
这个分类下最典型的情况是屏幕翻转,至于为什么分到资源文件改变相关,只要知道res目录下有不同的图片和资源文件对应不同的屏幕分辨率就可以了,类似的横竖屏也是有不同的资源文件对应的,只不过大部分情况下我们是只写一套资源的,(例如Android自带的侧滑菜单,竖屏模式下需要滑动才能显示,横屏模式下直接就显示在侧边,这就是横竖屏资源文件的应用之一),这类情况下的生命周期如下图所示:
图上显示的只是一个大概的流程,表面了当遇到此类异常情况的时候Activity会回调onSaveInstance方法来保存数据,然后Activity销毁,但是会自动重新创建,然后恢复之前保存的数据,然后到达运行状态.其中有一些细节需要注意:
遇到此类异常Activity被销毁的时候,onPause , onStop , onDestory都会走一遍
onSaveInstanceState方法只会在异常情况下被调用,正常的用户操作是不会触发这一方法的
onSaveInstanceState方法的回调时机是不确定的,但一定是在onStop之前,当然也是onDestory之前,可能在onPause之前也可能在onPause之后
onRestoreInstanceState只会在异常情况下有数据保存的时候才会在启动过程中调用,而且一旦调用其中传的Bundle对象一定是不为空的,类似的onCreate中也有Bundle对象,但是需要判空操作.
当Activity异常保存数据的时候,其承载的View也需要保存数据,具体的流程是
当Activity发生异常需要保存数据的时候,回调onSaveInstanceState方法,Activity会委托WIndow去保存数据,Window接到请求时会委托其顶级容器,顶层容器一一通知子View来保存数据,典型的委托思想.
资源文件变化所引起的生命周期变化其实是可以避免的,当资源文件变换的时候不想重新创建Activity的时候可以给Activity指定configuration属性,具体的属性值标示如下
项目
含义
mcc
SIM卡唯一标示IMSI中的国家代码,三位数字组成,次标示标示mcc代码发生改变(自己的理解是切换国家)
mnc
SIM卡唯一标识IMSI的运营商代码,移动为00,联通为01,电信为03,此项标识标识mnc发生改变
locale
设备的本地地址发生了改变,一般指切换了系统语言
touchscreen
触摸屏发生了改变,正常情况下不会发生
keyboard
键盘类型发生了改变,比如使用外接键盘
keyboardHidden
键盘的可访问性发生了改变,比如调出了键盘
navigation
系统导航方式发生了改变,比如使用轨迹球
screenLayout
屏幕的布局发生了改变,比如使用了外接设备
fontScale
系统字体的缩放比例发生了改变,比如更换了字体
uiMode
用户界面模式发生了改变,比如说使用夜间模式
orientation
屏幕方向发生了改变,最常用的之一
screenSize
屏幕的尺寸信息发生改变,搭配orientation一起使用禁止屏幕旋转重走生命周期
smallesScreenSize
屏幕尺寸发生改变,但是只针对物理屏幕尺寸,比如说切换到外接屏幕
layoutDirection
布局发生改变,较少使用
使用方法举例,比如说忽略屏幕旋转时候的生命周期改变
...
android:configChanges = "orientation|screenSize"
...
...
资源不足的情况下导致低优先级Activity被杀死的异常情况
优先级排序:
当系统内存不足的时候,系统就会按照上述优先级去杀死目标Activity所在的进程,并通过onSaveInstanceState和onRestoreInstanceState来保存和恢复数据.如果一个进程没有四大组件在执行,那么这个进程将会很快被系统杀死.其异常的生命周期方法与资源文件相关异常情况下的生命周期方法相同,就不啰嗦了.
Activity的启动模式详解:
启动模式概述:默认情况下,多次启动同一个Activity的时候,系统会穿件多个实例并把他们一一放入栈中,当单机back键,这些Activity会一一回退出栈.多次启动同一个Activity会创建多个实例显得浪费内存,所以需要启动模式来调整Activity的启动.
一共有四种启动模式:
standard : 标准模式,系统默认的模式,每次创建Activity都会重现创建一个新的实例,不管这个实例是否已经存在,生命周期符合典型的生命周期.这种模式下,谁启动了这个Activity,这个Activity就会运行在启动它的那个Activity所在的栈中,所以如果使用非Activity类型的Context(例如:ApplicationContext)去启动Activity就会报错,解决办法就是指定FLAG_ACTIVITY_NEW_TASK标记位,这样启动的时候就会为他创建一个新的任务栈.
singleTop : 栈顶复用模式:这种模式下,如果当前Activity已经位于任务栈的顶部,则不会重新创建实例,只会回调其newIntent方法,也不会重走生命周期,如果不在栈顶,则创建实例.
singleTask : 栈内服用模式:这种模式下,如果栈内存在Activity的实例,则将其上面的所有Activity出栈,直到那个Activity处于栈顶为止,只会回调其newIntent方法,如果不存在,则创建实例.
singleInstance : 单实例模式.相当于加强版的singleTask模式,除了具有singleTask的特性之外,还加了一点,就是使用此模式的Activity只能单独的处于一个任务栈中
四种启动模式的应用场景:
standard 模式,没有特殊需求的都默认使用的这个模式
singleTop模式 :使用于通过通启动的Activity.例如新闻推送,显示新闻详情的界面就应该设置为singleTop,因为如果每一次点击通知启动新闻详情都打开一个Activity,回退的时候会有很不好的体验
singleTask 模式 :适用于会被其他程序调起但是不想显示之前界面的Activity,例如浏览器,不管被多少个应用访问网站功能调用,都显示的是主界面
singleInstance 模式 :适用于与程序分开的页面,比如闹钟提醒,闹钟的提醒界面和闹钟的设置界面就应该分开
主要是作者在启动模式这方面使用的比较少,平时没太大注意,所以能说的少一些,以后有新的内容会来补充的.
最后安利一下一个新手交流的QQ群,欢迎加入,群号:375276053
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。