如从竖屏切换到横屏时,系统配置发生改变导致活动被销毁,其onPause,onStop和onDestroy方法均会被调用,同时由于活动是异常终止,系统会调用onSaveInstanceState来保存当前活动的状态。这个方法调用时机是在onStop方法后,但它和onPause方法没有时序关系。活动被重新创建后,系统会调用onRestoreInstanceState方法,并把活动销毁时onSaveInstanceState方法保存的Bundle对象作为参数传给onRestoreInstanceState和onCreate方法。因此可以通过onRestoreInstanceState和onCreate两个方法来判断活动是否被重建并把保存的数据进行恢复。
保存和恢复View的层次结构,系统的工作流程类似与View对事件的分发:首先活动被意外终止时,它会调用onSaveInstanceState来保存数据,然后Activity委托Window保存数据,接着Window再委托它上面的顶级容器保存数据,顶层容器一般为DecorView。最后像View对事件的分发一样,顶层容器一一通知它的子元素保存数据。
可以指定Activity中的configChanges属性,使系统配置发生变化时,不重建Activity
在AndroMenifest.xml的Activity声明configChanges的值,可以在系统配置发生改变时,使系统不会重建该Activity。常用的
configChanges属性:locale(设备本地位置发生变化) orientation(屏幕方向发生变化)和keyboardHidden(隐藏键盘)这三个选项
首先看一下Activity的优先级,优先级由高到低分为三种:
(1) 前台Activity:正在和用户交互的活动,优先级最高
(2) 可见但非前台Activity:如Activity中弹出了一个对话框,导致Activity可见但位于后台,无法和用户直接交互。
(3) 后台Activity:已经被暂停的活动,如执行力onStop,优先级最低
当系统内存不足时,就会按照上面的优先级杀死目标活动所在进程,并在后续通过onSaveInstanceState和onRestoreInstanceState储存和恢复数据。
1.在AndroidMenifest.xml中的activity标签中加入android:launchMode属性,值为上面四种模式之一
2.在Intent中通过标志位指定,例如:
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
两种设置方式有一定的区别:首先,第二种的优先级高于第一种;其次,两者在限定范围上有不同
常用的Flags
FLAG_ACTIVITY_NEW_TASK
这个标记位作用是为Activity指定“singleTask”启动模式
FLAG_ACTIVITY_SINGLE_TOP
这个标记位作用是为Activity指定“singleTop”的启动模式
FLAG_ACTIVITY_CLEAR_TOP
具有此标记位的Activity,当他启动时在同一个任务栈中所有位于他上面的Activity都有出栈。
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
具有此标志的Activity,不会出现在历史Activity列表中
概述
为了匹配过滤列表,需要同时匹配过滤列表中的action,category,data三项信息,否则匹配失败。一个过滤列表中的action,category,data可以有多个。另外,一个活动可以有多个intent-filter,一个Intent只要能匹配任何一组intent-filter即可成功启动对应Activity。
action是一个字符串,Intent中的action必须能和过滤规则中的action匹配,即和action的字符串值完全一样。一个活动可以有多个过滤规则,一个过滤规则可以有多个action,只要Intent中的action能和任一过滤规则中任一action相同即可匹配成功,否则匹配失败。另外,action区分大小写;系统预定义了一些action,我们也可以使用自定义action。再有,如果action匹配了多个activity,系统会提示从多个activity中选择一个打开,如下图所示;如果匹配了一个activity就会直接跳转到该活动。
**在Intent中设置action:**intent.setAction(String string)
category也是字符串,系统也预定义了一些category,也可以自定义。其匹配规则和action不同,如果Intent中如果含有category,那么所有的category都必须和过滤规则中的其中一个category相同。即如果Intent中出现了category,不管有几个,对于每个category都必须是过滤规则中已经定义了的。另外,如果Intent中没有category,则默认匹配成功;系统在调用startActivity或StartActivityForResult会默认为Intent加上”abdroid.intent.category.DEEAULT”这个category。所以为了我们的Activity能够隐式调用Activity,就必须在intent-filter中指定“abdroid.intent.category.DEEAULT”这个category。
**在Intent中设置category:**intent.addCategory(String category)
data由两部分组成:mimeType(媒体类型,如image,jpeg等)和URI,URI包含的数据较多,其结构如下:
<scheme>://<host>:<port>/[<path>|<pathPrefix>|<pathPattern>]
每个数据的含义:
Scheme:URI的模式,比如https,file,content等,如果URI没有指定scheme,则整个URI的其他参数无效,即URI无效。
Host:URI的主机名,如www.baidu.com,如果host未指定,那么URI的其他参数无效,即URI无效。
Port:端口号,如8080,仅当URI中制定了scheme和host参数时port参数才有意义。
Path,pathPattern和pathPrefix:这三个参数表述路径信息,其中path表示完整路径信息,pathpattern也表示完整信息,但是他的可以包含通配符 “*”。pathPrefix表示路径的前缀信息
data的匹配规则和action类似,它要求Intent中必须含有data数据,并且data数据能够完全匹配过滤规则中的某一个data
**给Intent中同时设置data和type只能用函数setDataAndType:**setDataAndType(Uri data, String type)
设置data:setData(Uri data) 设置type:setType(String type)
最后,当我们通过隐式方式启动一个活动时可以通过PackageManager或Intent的resolveActivity方法判断能否匹配Activity,如果找不到匹配的就返回null
《安卓开发艺术探索》