第一章 Activity的生命周期和启动模式
-
在 onRestoreInstanceState 或 onCreate 中恢复数据的区别
在 onSaveInstanceState 中存储数据后,可以通过 onRestoreInstanceState 或 onCreate 获取,两者区别是:onRestoreInstanceState 一旦被调用,其参数 Bundle savedInstanceState 一定有值,不需要额外地判断是否为空。但 onCreate 不行,onCreate 如果正常启动的话,其参数 Bundle savedInstanceState 为null。【官方推荐通过 onRestoreInstanceState 方法恢复数据】 -
Activity 的 launchMode
1、standard:标准模式,每次启动一个 Activity 都会重新创建一个新的实例。在这种模式下,谁启动了这个 Activity,那么这个 Activity 就运行在启动他的那个 Activity 所在的栈中。
2、singleTop:栈顶复用模式,在该种模式下,如果新 Activity 已经位于任务栈的栈顶,那么此 Activity 不会被重新创建,同时它的 onNewIntent 方法会被回调,通过此方法的参数我们可以取得当前请求的信息。
3、 singleTask:栈内复用模式,在这种模式下,只要 Activity 在一个栈中存在,那么多次启动此 Activity 都不会重新创建实例,同时系统会回调其 onNewIntent 方法。
4、 singleInstance:单实例模式,singleTask 增强版,除了具有 singleTask 的特性,还加强了一点,那就是具有此种模式的 Activity 只能单独地位于一个任务栈中。 -
如何给 Activity 指定启动模式
① 通过 AndroidManifest 为 Activity 指定启动模式
<activity
android:name ="com.shirt.test.SecondActivity"
android:configChanges = "screenLayout"
android:launchMode = "singleTask"
android:label = "@string/app_name"/>
② 通过在 Intent 中设置标志位来为 Activity 指定启动模式
Intent intent = new Intent(MainActivity.this,SecondActivity.class)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(intent)
两者区别:① 优先级上第二种方式的优先级高于第一种;② 限定范围不同,第一种方式无法直接给 Activity 设定 FLAG_ACTIVITY_CLEAR_TOP 标识,第二种方式无法为 Activity 指定 singleInstance 模式。
-
Activity 的 Flags
① FLAG_ACTIVITY_NEW_TASK :指定 Activity的启动模式 singleTask
② FLAG_ACTIVITY_SINGLE_TOP :指定 Activity 的启动模式 singleTop
③ FLAG_ACTIVITY_CLEAR_TOP :具有此标记位的 Activity,当它启动时,在同一个任务栈中所有位于它上面的 Activity 都要出栈。一般会和 singleTask 启动模式一起出现,在这种情况下,被启动 Activity 的实例如果已经存在,那么系统就会调用它的 onNewIntent。如果被启动的 Activity 采用 standard 模式启动,那么它连同它之上的 Activity 都要出栈,系统会创建新的 Activity 实例并放入栈顶。singleTask 启动模式默认就具有此标记位的效果。
④ FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS :具有此标记位的 Activity 不会出现在历史 Activity 的列表中,等同于在 XML 中指定 Activity 的属性 androidLexcludeFromRecents = "true"。 -
IntentFilter 的匹配规则
<activity
android:name = "com.shirt.test.ThirdActivity"
<intent-filter>
<action android:name = "com.shirt.test.c"/>
<action android:name = "com.shirt.test.d/>
<category android:name = "com.shirt.test.c/>
<category android:name = "com.shirt.test.d/>
<category android:name = "android.intent.category.DEFAULT"/>
<data android:mimeType = "text/plain/>
</intent-filter>
</activity>
① action 的匹配规则:Intent 中的 action 必须能够和过滤规则中的 action 的字符串值匹配(区分大小写),只要 Intent 中的 action 能够和过滤规则中的任何一个 action 相同即可匹配成功。
② category 的匹配规则:Intent 中如果含有 category,那么所有的 category 都必须和过滤规则中的其中一个 category 相同,如果没有category,这个 Intent 仍然可以匹配成功。ps:与 action 的规则不同在于, action 时要求 Intent 中必须有一个 action 且必须能够和过滤规则中的某个 action 相同;而 category 要求 Intent 可以没有 category ,但如果有,不管有几个,每个都要和过滤规则中的任何一个 category 相同。
③ data 的匹配规则:如果过滤规则中定义了 data,那么 Intent 中必须也要定义可匹配的 data。
<data android:scheme = "string"
android:host = "string"
android:port = "string"
android:path = "string"
android:pathPattern = "string"
android:pathPrefix = "string"
android:mimeType = "string"/>
data 由两部分组成,mimeType 和URI。mimeType 指媒体类型,比如 image/jpeg(图片)、audio/mpeg4-generic(文本)、video/*(视频)等,URI 中包含数据较多,下面是 URI 的结构
<scheme>://<host>:<port>/[<path>|<pathPrefix>|<pathPattern>]
例如:content://com.exaple.project:200/folder/subfolder/etc
http://www.baidu.com:80/search/info
Scheme:URI 的模式,比如 http、file、content 等,如果 URI 中没有指定 scheme,那么整个 URI 的其他参数无效。
Host:URI 的主机名。
Port:URI 的端口号,仅当 URI 中指定了 scheme 和 host 参数的时候 port 参数才有意义。
Path、pathPattern、pathPrefix:这三个参数表述路径信息。path 表示完整的路径信息;pathPattern 也表示完整路径,但它里面可以包含通配符“*”;pathPrefix 表示路径的前缀信息。