异常情况下生命周期的分析
在前面自己复习了Activity的生命周期方法,现在我们来分析Activity异常情况下的生命周期方法调度。常见的异常有两种资源,相关的系统配发生改变导致Activity被杀死并重新创建,另种情况是内存资源不足导致低优先Activity被杀死。
1.资源配置发生改变,以横竖屏切换为列来说明:
在Activity 处于竖屏状态,突然旋转手机,由于系统配置发生了改变,在默认情况下Activity会被销毁并且重建,当然我们也可以阻止系统的重建我们的Activity。
在默认情况下,如果我们的Activity不做特殊处理,那么我们的系统配置发生改变后,Activity的生命周期方法执行顺序:
onPause()-->onSaveInstanceState() -->onStop()-->onDestroy()-->onCreate()-->onStart()-->onRestoreInstanceState()-->onResume()
则表示在资源配置发生改变后,Activity会被销毁,其中onPause ,onStop,onDestory均会被调用,并且由于Activity是在异常状态下销魂的,所以在调用onStop之前会先调用onSaveInstanceState来保存当前Activity的状态。而且onSaveInstanceState可能在onPuase之前调用,如果Activity被重建后系统将onSaveInstanceState方法里保存的的Bundle对象作为参数同时传给了onCreate和onRestoreInstanceState方法。我们可以通过判断这两个方法来判断Activity是否被重建了。在onSaveInstanceState和onRestoreInstanceState中系统自己为我们做了一定的工作,当Activity在异常情况下需要重建是,系统会默认为我们保存当前Activity的视图结构,并且在Activity重启后为魔门恢复这些东西,比如:文本框中用户输入的数据、listView的滚动位置。和Activity一样每个View也有onSaveInstanceState和onRestoreInstanceState这两个方法。
关于保存和恢复View的层次结构系统工作流程如下:首先Activity被意外终止时,Activity调用onSaveInstanceState去保存数据,然后为委托Window去保存数据,接着Window在委托他上面的顶层容器去保存数据。顶层容器是一个ViewGroup,一般来说它可能是DecorView,最后顶层容器再去一一通知他的子元素来保存数据,这样整个数据保存过程就完成了。
2.内存资源不足导致低优先级的Activity被杀死。
首先在这我们先讲一讲Activity的优先级,Activity按照优先级从高到低可以分为三种:
(1)前台Activity——正在和用户交互的Activity,优先级最高。
(2)可见但非前台Activity——比如Activity中弹出了一个对话框,导致Activity可见但是位于后台无法和用户进行直接交互。
(3)后台Activity——已经被暂停的Activity,比如执行了onStop,优先级最低。
当系统内存不值得时u,系统就会按照优先级去杀死Activity所在进程,并在后续通过onSaveInstancState和onRestoreInstanceState来存储和恢复数据。
IntentFilter的匹配规则
讲这个知识之前我们应该先讲一下Activity的启动。Activity的启动分为两种隐式和显示调用.
1.显示启动
Intent intent=new Intent(MainActivity.this, SecondActivity.class);
startActivity(intent);
2.隐式启动
AndroidManifest.xml中定义某个Activity的intent-fliter
<intent-filter>
<action android:name="com.example.activity.ACTION_START"/>
<category android:name = "com.example.activity.ACTION_START"
</intent-filter>
Activity中
Intent intent = new Intent("com.example.activity.ACTION_START");
//android.intent.category.DEFAULT是一种默认的category,在startActivity时自动添加
intent.addCategory("com.example.activity.ACTION_START";
startActivity(intent);
隐式启动,在启动的时候是不明确的,需要匹配系统或AndroidManifest.xml中的intent-filter定义,只有action和category和data完全匹配时,才会启动.隐式启动不仅可以启动自己的Activity,还可以启动其他的Activity,如打开网页
隐式调用需要Intent能够匹配目标组件的IntentFilter中所设置的过滤信息,Intent中油Action、category、data。另外一个Activity可以有多个IntentFilter,一个intent只要匹配上任意一组intent-filte即可启动对应的Activity
1.action的匹配规则
Action是一个字符串,系统预定义了一些action,同时我们在应用中可以定义自己的action。action的匹配规则是Intent中action必须能够和过滤规则中的action匹配。一个过滤规则中有一个或是对个action,只要Intent中的action值于任意一个action值匹配成功,即actio匹配成功。
2.category的匹配规则
category是一个字符串,和action一样系统也预定义了一些,并可以自己定义category。category的匹配规则和action的匹配规则不一样,他要求如果Intent中含有category,那么category都必须和过滤规则中其中一个相同。也就是说如果一个Activity有三个intent-filter,intent中添加了category的话,至少应该添加三个category。但是Intent中可以不用添加category因为如果不添加系统在调用startActivity或是调用startActivityForResultde shihou 会默认给加上“Android。intent.category.DEFULT”.
3.data的匹配规则
data的匹配规则和action类似,如果过滤规则中定义了data,那么Intent中也必须定义可匹配的data。
data又两部分组成,mimeTyoe和URI。mimeType指媒体类型,比如iamge/jpeg、audio/mpeg4-generic和video/*等。可以表示图片、文本、视频等不同媒体格式。URI的结构<scheme>://<host>:<port>/[<path>|<pathPrefix>|<pathPattern>];
data 它要求intent中必须含有data书数据,并且data数据能够与完全匹配过滤规则中的某一个。