Android Activity生命周期和启动模式

一、Activity生命周期

activity正常的生命周期:

1.onCreate

表示Activity正在被创建,第一个回调,在里面可以做一些初始化工作,比如调用setContentView去加载界面布局资源】、初始化Activity所需的数据。

2.onRestart

表示Activity正在重新启动。一般情况下,当Activity从不可见到可见状态时,Restart就会被调用。

3.onStart

表示Activity正在被启动,即将开始。这时Activity已经可见了,但是还没有出现在前台,还不能和用户交互。

4.onResume

表示Activity已经可见了,并且出现在前台并开始活动。已经是可交互状态了。

5.onPause

表示Activity正在停止,正常情况下,紧接着onStop就会被调用。此时可以做一些存储数据、停止动画等工作,但不能太耗时,因为这会影响到新Activity的显示,旧Activity必须执行完onPause,新Activity的onResume才会执行。

6.onStop

表示Activity即将停止,可以做一些稍微重量级的回收工作,同样不能太耗时。

7.onDestroy

表示Activity即将被销毁,这是Activity生命周期的最后一个回调,在里面我们可以做一些回收工作和最终的资源释放。

当用户打开新的Activity或者切换到桌面的时候,回调如下:onPause->onStop。

这里有一种特殊情况,如果新Activity采用了透明主题,那么当前Activity不会回调stop。

activity异常情况下的生命周期

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

Activity-onSaveInstanceState-onDestory

Activity-onCreate-onRestoreInstanceState

onCreate和onRestoreInstanceState区别:

onRestoreInstanceState一旦被调用,其参数Bundle savedInstanceState一定是有值的,我们不需要额外判空。但是onCreate,如果是正常启动的话,其参数savedInstanceState为null。所以如果需要恢复数据的话,我们一般在onRestoreInstanceState里面。

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

Activity优先级:

前台Activity > 可见但非前台Activity(比如Activity中弹出了一个对话框,导致Activity可见但是位于后台无法和用户直接交互)> 后台Activity。

Android:configChanges

我们知道在运行时发生配置变更时,默认情况下会关闭Activity并将其重启,但是使用该属性声明配置将阻止Activity重启。相反,Activity会保持运行状态,并且系统会调用其onConfigurationChanged()方法。任何或所有下列字符串均是该属性的有效值。若有多个值,则使用 "|" 进行分隔,例如:"locale|navigation|orientation"。

值    描述
"density"    显示密度发生变更 - 用户可能已指定不同的显示比例,或者有不同的显示现处于活跃状态。此项为API24中的新增配置

"fontScale"    字体缩放系数发生变更 - 用户已经选择新的全局字号
"keyboard"    键盘类型发生变更 - 例如,用户插入外置键盘
"keyboardHidden"    键盘无障碍功能发生变更 - 例如,用户显示硬键盘
"layoutDirection"    布局方向发生变更 - 例如,自从左至右(LTR)更改为从右至左(RTL)。
"locale"    语言区域发生变更 - 用户已为文本选择新的显示语言
"mcc"    IMSI 移动设备国家/地区代码(MCC)发生变更 - 检测到SIM 并更新 MCC。·
"mnc"    IMSI 移动设备网络代码(MNC) 发生变更 - 检测到 SIM 并更新 MNC。
"navigation"    导航类型(轨迹球/方向键)发生变更。(这种情况通常不会发生)
"orientation"    屏幕方向发生变更 - 用户旋转设备。

请注意:如果应用面向Android 3.2 (API13)或者更高版本的系统,则还应声明 "screenSize" 配置,因为当设备在横向与纵向之间切换时,该配置也会发生变更

"screenLayout"    屏幕布局发生变更 - 不同的显示可能处于活跃状态

例如:页面由全屏切换到分屏状态或由分屏状态切换到全屏状态时可以使用此属性值

"screenSize"    当前屏幕尺寸发生变更。该值表示当前可用尺寸相对于当前纵横比的变更,当用户在横向和纵向之间切换时,它便会发生变更。

"smallestScreenSize"    物理尺寸发生变更。

该值表示与方向无关的尺寸变更,因此它只有在实际物理屏幕尺寸发生变更(如切换到外部显示器,或者在pad中的PC模式下,全屏与小屏的切换)时才发生变化。对此配置所变更对应smallestWidth配置的变化。

"touchScreen"    触摸屏发生变更。(这种情况通常不会发生)
"uiMode"    界面模式发生变更 - 用户已将设备置于桌面或车载基座,或者夜间模式发生变更。

深色模式与浅色模式相互切换时可以使用此属性值。

二、Activity的启动模式

四种方式:standard,singleTop,singleTask,singleInstance

1.standard:标准模式

每次启动都会重新创建一个新的实例,不管这个实例是否已经存在。

当我们使用ApplicationContext去启动standard模式的Activity的时候会报错。

因为standard模式的Activity默认会进入启动它的Activity所属的任务栈中,但是由于非Activity类型的Context(比如ApplicationContext)并没有所谓的栈,所以就有问题了。解决这个问题的方法是为待启动Activity指定FLAG_ACTIVITY_NEW_TASK标记位,这样启动的时候就会为它创建一个新的任务栈,这个时候待启动Activity实际上是以singleTask模式启动的。

2.singleTop:栈顶复用模式。

在这种模式下,如果新Activity已经位于任务栈的栈顶,那么此Activity就不会被重新创建,同时它的onNewIntent方法会被回调。

3.singleTask:栈内复用模式

这是一种单实例模式,在这种模式下,只要Activity会在一个栈中存在,那么多次启动此Activity都不会重新创建实例,和singleTop一样,系统也会回调其onNewIntent。

当一个具有singleTask模式的Activity请求启动后,比如Activity A,系统首先会寻找是否存在A想要的任务栈,如果不存在,就重新重建一个任务栈,然后创建A的实例后把A放在栈中。如果存在A所需的任务栈,这时要看A是否在栈中有实例存在,如果存在的话,就会把A上面的其他Activity的实例clear,将A调到栈顶并调用它的onNewIntent方法,如果不存在,就创建A的实例,并把A压入栈中。

TaskAffinity属性为栈的名字。一般默认栈的名字为包名。

TaskAffinity和allowTaskReparenting共同使用。

当一个应用A启动了应用B的某个Activity后,如果这个Activity的allowTaskReparenting为true的话,那么当应用B被启动后,此Activity会直接从应用A的任务栈转移到应用B的任务栈。

4.singleInstance:单实例模式

这是一种加强模式的singleTask,它除了有singleTask模式所有的特性外,还加强了一点。就是具有此模式的Activity只能单独地位于一个任务栈中。

Activity的Flags

Activity的Flags主要有以下这些:

FLAG_ACTIVITY_NEW_TASK和 singleTask 效果一样

FLAG_ACTIVITY_SINGLE_TOP和singleTop效果一样

FLAG_ACTIVITY_CLEAR_TOP, singleTask默认是具有此标志位的效果。

FLAG_ACITIVITY_EXCKUDE_FROM_RECENTS,具有这个标志的Activity不会出现在历史Activity的列表中。和android:excludeFromRecents="true"效果一样。

三、IntentFilter的匹配规则

我们启动Activity分两种:显示调用和隐式调用。

原则上一个Intent不应该既是显示调用又是隐式调用,如果二者都存在的话,以显示调用为主。

IntentFilter中的过滤信息有action、category、data

只有一个Intent同时匹配action类别、category类别、data类别才算完全匹配,只有完全匹配才能成功启动目标Activity。另外,一个Activity中可以有多个intent-filter,一个Intent只要能匹配任何一组intent-filter即可成功启动对应的Activity。

action的匹配规则

action是一个字符串(区分大小写),系统预定义了一些action,同时我们也可以在应用中定义自己的action。

action的匹配规则是Intent中的action必须能够和过滤规则中的action匹配。一个过滤规则中可以有多个action,那么只要Intent中的action能够和过滤规则中的任何一个action相同即可匹配成功。

category的匹配规则

category也是一个字符串,系统预定义了一些category。同时我们也可以自定义自己的category。

category的匹配规则和action不同,它要求Intent中如果含有category,那么所有的category都必须和过滤规则中的其中一个category相同。

action要求Intent中必须有一个action且必须能够和过滤规则中的某个action相同,而category要求Intent可以没有category,但是如果你一旦有category,不管有几个,每个都要能够和过滤规则中的任何一个category相同。

不设置category也能匹配成功,原因是系统在startActivity或者startActivityForResult的我时候会默认为Intent加上“android.intent.category.DEFAULT”这个category。为了我们的activity能够接收隐式调用,就必须在intent-filter中指定“android.intent.category.DEFAULT”这个category。

data的匹配规则

data的匹配规则和action类似,如果过滤规则中定义了data,那么Intent中必须也要定义可匹配的data。

data由两部分组成,mimeType和URI。其中mimeType是指媒体类型,比如image/jpeg,audio/mpeg4-generic和video/*等,可以表示图片、文本、视频等不同的媒体格式,而URI中能包含的数据就比较多了。

URI: Scheme,Host,Port

data的匹配规则和action类似,它要求Intent中必须含有data数据,并且data数据能够完全匹配过滤规则中的某一个data。

如果要为Intent指定完整的data,必须调用setDataAndType方法,不能先调用setData再调用setType,因为这两个方法会彼此清除对方的值。

最后,当我们通过隐式方式启动一个Activity的时候,可以判断一下是否有Activity能够匹配我们的隐式Intent。可以采用PackageManager的resolveActivity方法或者Intent的resolveActivity方法,如果它们找不到匹配的Activity就会返回null。

  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值