内容简介:
1、Activity的生命周期全面分析
2、Activity的四种启动模式
3、IntentFilter的匹配规则
一、Activty生命周期
典型情况下:
Q: Activity生命周期分析
(1) onCreate()
状态:Activity正在被创建;
开发者工作:可做一些初始化工作,如调用setContentView去加载界面布局资源、初始化数据
(2) onRestart()
状态:Activity正在重新启动;
当前Activity从不可见=》可见,这种情形一般是由用户行为导致,比如用户按Home键切换到桌面或者用户打开了一个新 的Activity,接着用户又回到了这个Activity。
(3) onStart()
状态:Activity正在被启动;这时Activity可见但还未出现在前台,无法和用户进行交互。
(4) onResume()
状态:Activity获得焦点;这时Activity可见且出现在前台,并开始活动。
(5) onPause()
状态:Activity正在停止;这时Activity可见且出现在前台,并开始活动。
开发者工作:可做一些存储数据、停止动画等工作,避免耗时操作。
注意:Activity切换时,旧Activity的onPause必须先执行完,新Activity的onResume才会执行。
(6) onStop()
状态:Activity即将停止;
开发者工作:可做稍微重量级回收工作,如取消网络连接、注销广播接收器等,避免耗时操作。
注意:如果新的Activity采用了透明主题,那么当前Activity 将不会调用onStop()
(7) onDestory()
状态:Activity即将被销毁;
开发者工作:可做回收工作和最终的资源释放。
onStart()和onResume()、onPause()和onStop()的区别: onStart与onStop是从Activity是否可见这个角度调用的,onResume和onPause是从Activity是否显示在前台这个角度来回调的,在实际使用没其他明显区别。
Q: Activity的切换过程
(1) Activty 第一次启动:
onCreate() => onStart()=>onResume()
(2) 打开新的Activity:
旧的Activity的onPause() => 新的Activity的onCreate() =>新的Activity的onStart()=>新的Activity的onResume() =>旧的Activity的onStop()
(3) 再次回到原Activity:
新Activity的onPause() => 旧Activity的onRestart() => onStart() => onResume() => 新Activity的onStop() => onDestory();
(4) 切换到桌面:
onPause() => onStop()
(5) 按下Back键:
onPause() => onStop() => onDestory()
异常情况下:
Q: Activity生命周期分析
情况1:资源相关的系统配置发生改变导致Activity被杀死并重新创建
例如屏幕发生旋转:当竖屏切换到横屏时,默认情况下,系统将会调用onSaveInstanceState()方法来保存当前Activity的状态,该方法在onStop之前调用,和onPause的调用顺序没有特定关系,然后当前Activity将会被销毁,接着重建一个新的Activity,并调用onRestoreInstanceState()方法恢复数据(例如文本框中用户输入的数据、ListView滚动的位置等),该方法在onStart之后调用。
Activity的生命周期切换如下:
onSaveInstanceState() => (onPause)(不定)=>onStop()=>onDestory() => onCreate() => onStart() => onRestoreInstanceState() => onResume()
保存和恢复View层次结构时,系统的工作流程为:
Activity异常终止 => Activity调用onSaveInstanceState()保存数据 => Activity委托Window保存数据 => Window委托顶级容器保存数据 => 顶层容器再去一一通知它的子元素保存数据。
Q1:如何避免系统配置发生改变后Activity重建?
可在AndroidManifest.xml中对应的Activity中设置android:configChanges="orientation|screenSize"。此时再次旋转屏幕时,该Activity不会被系统杀死和重建,只会调用onConfigurationChanged。因此,当配置程序需要响应配置改变,指定configChanges属性,重写onConfigurationChanged方法即可。
情况2:资源内存不足时导致低优先级的Activity被杀死
- Activity优先级排序: 前台Activity =》 可见但非前台Activity(前台Activity弹出Dialog) =》 后台Activity
- 当系统内存不足时,会按照Activity优先级从低到高去杀死目标Activity所在的进程。
- 若一个进程没有四大组件在执行,那么这个进程将很快被系统杀死。
二、Activty启动模式
Q: Activity的LaunchMode
standard: 标准模式、默认模式
状态: 每次启动一个Activity都会重新创建一个新的实例,不管该实例是否已经存在。
说明:ActivityA 启动了 ActivityB(B是标准模式),那么B就会进入到A所在的栈中。
注意:用ApplicationContext去启动standard模式的Activity会报错,原因是standard模式的Activity会默认进入启动它所属的任务栈,非Activity类型的Context并没有所谓的任务栈。
================================================================================================
singleTop:栈顶复用模式
状态:如果新Activity已经位于任务栈的栈顶,那么此Activity不会被重新创建,同时它的onNewIntent方法会被回调,通过此方法的参数我们可以取出当前请求的信息。若新Activity的实例已存在但不是位于栈顶,那么Activity仍然会被重建。
说明:假设目前栈内的情况为ABCD,ABCD为四个Activity,此时启动ActivityD(D是singleTop),则栈内情况依然为ABCD
singleTask:栈内复用模式
状态:只要该Activity在一个任务栈中存在,都不会重新创建,并回调onNewIntent(intent)方法。如果不存在,系统会先寻找是否存在需要的栈,如果不存在该栈,就创建一个任务栈,并把该Activity实例放进去;如果存在该栈,栈内存在该Activity的实例,那么系统就会把ActivityA调到栈顶,并回调它的onNewIntent方法;栈内不存在该Activity实例,系统就会创建该Activity的实例到已经存在的栈中。
singleInstance:单实例模式
状态:具有此模式的Activity只能单独位于一个任务栈中,且此任务栈中只有唯一一个实例。
标识Activity任务栈名称的属性:android:taskAffinity,默认为应用包名。
Q:设置Activity启动模式的方法
1、通过AndroidManifest为Activity指定启动模式: android:launchMode=“singleTask”
2、通过在Intent中设置标志位来为Activity指定启动模式:intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Q:常用的可设定Activity启动模式的标记位
FLAG_ACTIVITY_SINGLE_TOP:对应singleTop启动模式。
FLAG_ACTIVITY_NEW_TASK :对应singleTask模式。
FLAG_ACTIVITY_CLEAR_TOP: 当该Activity启动时,同一任务栈中所有位于该Activity上面的Activity都要出栈
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS :等同于为Activity指定属性 android:excludeFromRecents="true"
三、IntentFilter的匹配规则
原则:
①一个intent只有同时匹配某个Activity的intent-filter中的action、category、data才算完全匹配,才能启动该Activity。
② 一个Activity可以有多个 intent-filter,一个 intent只要成功匹配任意一组 intent-filter,就可以启动该Activity。
a. action匹配规则:
- 要求intent中的action 存在且必须和intent-filter中的其中一个 action相同。
- 区分大小写。
b. category匹配规则:
- intent中的category可以不存在,这是因为此时系统给该Activity 默认加上了< category android:name="android.intent.category.DEAFAULT" />属性值。
- 除上述情况外,有其他category,则要求intent中的每一个category都能够和intent-filter中的任一category 相同。
c. data匹配规则:
- 如果intent-filter中有定义data,那么Intent中也必须要定义可匹配的data。
- data主要由mimeType(媒体类型)和URI组成。在匹配时通过intent.setDataAndType(Uri data, String type)方法对date进行设置。
采用隐式方式启动Activity时,可以用PackageManager的resolveActivity方法或者Intent的resolveActivity方法判断是否有Activity匹配该隐式Intent。
参考:厘米姑娘