onCreate(): 表示Activity正在被创建,这是生命周期的第一个方法,在这个方法中我们可以做一些初始化工作,比如调用setContentView去加载界面布局资源,初始化Activity所需数据
onRestart(): 表示Activity正在重新启动。一般情况下,当当前Activity从不可见,重新变成可见状态时,onRestary就会被调用。这种情况一般是用户行为所导致的,比如按Home键切换到桌面,或者用户打开一个新的activity,这时当前的Activity就会暂停,也就是onPause和onStop被执行了,接着用户又回到这个Activity,就会出现这种情况
onStart(): 表示Activity正在被启动,即将开始,这时Activity已经可见了,但还是没有出现在前台,还无法和用户交互。这个时候其实可以理解为Activity已经显示,但我们还看不到。
onResume(): 表示Activity已经可见了,并且出现在前台并开始活动。要注意和onStart()的对比,onStart和onResume都表示Activity已经可见,但是onStart()的时候Activity还在后台,onResume()的时候Activity才显示出来。
onPause(): 表示Activity正在停止,正常情况下,紧接着onStop就会被调用。在特殊情况下,如果这个时候快速回到当前的Activity,那么onRestart就会被调用,这种情况下属于极端情况,用户操作很难重现这一幕。此时可以做一些存储数据和停止动画的操作,但注意不能太耗时,因为这会影响新Activity的显示,onPause()先执行完,新的onResume才会执行。
onStop(): 表示Activity即将停止,可以做一些稍微重量级的回收工作,同样不能太耗时。
onDestroy(): 表示Activity即将被销毁,这是Activity生命周期中最后一个回调,在这里我们可以进行一些回收工作和最终的资源释放。
从整个生命周期来说,onCreate和onDestroy是配对的,分别标识着Activity的创建和销毁,并且只能又一次调用。从Activity是否可见来说,onStart和onStop是配对的,随着用户的操作或者设备屏幕的点亮和熄灭,这两个方面可能被调用多次;从Activity是否在前台来说,onResume和onPause是配对,随着用户的操作或者设备屏幕的点亮和熄灭,这两个方面可能被调用多次。
系统配置变化导致Activity销毁重建
这种情况比较典型的就是竖屏突然转换为横屏,由于系统配置发生改变,Activity就会销毁并重新创建。
这种情况下的Activity的生命周期,如图:
当Activity被销毁时,它的onPasuse,onStop,onDestoy均会被调用。但同时由于是异常情况终止的,系统在onStop之前回调用onSavaInstanceState来保存当前Activity的状态,它和onPause没有一定的时序关系。当Activity被重新创建后,系统在onStart之后调用onRestoreInstanceState来恢复之前保存的数据。.
保存数据的过程:Activity调用onSavaInstanceState去保存数据。然后Activity去委托Window去保存数据,紧接着window去委托他上面的顶级容器去保存数据,最后顶级容器去委托它的子元素来保存数据。
资源内存不足导致低优先级的Activity被杀死
Activity的优先级:①前台Activity ②可见但非前台的Activity ③后台Activity(执行了onStop)
当系统内存不足,系统会按照上述优先级回收目标Activity所在的进程,并在后续通过onSaveInstanceState和onRestoreInstanceState来恢复和存储数据。
指定Activity中的configChanges属性,使系统配置发生变化时,不重建Activity
在AndroMenifest.xml的Activity声明configChanges的值,可以在系统配置发生改变时,使系统不会重建该Activity。常用的
configChanges属性:locale(设备本地位置发生变化) orientation(屏幕方向发生变化)和keyboardHidden()这三个选项。
Activity目前一共有4种启动模式,分别是:standard,singleTop,singleTask,singleInstance.
标准模式,是Activity的默认启动模式,在不显示指定的情况下,所有活动都会自动使用这种启动模式,这种模式下,没启动一个新的Activity,他就会在任务栈中入栈,并处于栈顶位置,并不在乎任务栈中是否存在相同实例。
standard模式下。Activity的onCreate,onStart,onResume均会被调用。
栈顶复用模式:在这种模式下,如果新Activity已经处于任务栈栈顶,那么此Activity就不会被重新创建。
在singleTop模式下,Activity的onNewIntent方法会被回到,通过此方法的参数可以取出当前请求的信息。在这个Activity的onCreate,onStart不会被系统调用,因此它并不会发生什么变化。如果新的Activity存在但不存在与栈顶,那么新的Activity依然会重建。
栈内复用模式:这是一种单实例模式,这种模式下,只要Activity在一个栈内存在,那么多次启动此Activity都不会重新实例。
在singleTask模式下,和singlTop一样,系统也会回调其onNewIntent方法,一个具有singleTask模式的Activity请求启动后,系统首先会寻找A想要的任务栈,如果不存在,就重新创建一个任务栈,然后创建A的实例后,把A放到栈内。如果存在A所需的任务栈,这时就要看A是否栈内有实例,如果有实例存在,那么系统就会把A调到栈顶并调用onNewIntent方法,同时把A上面的所有Activity退栈,如果实例不存在,就创建A的实例并把A压入栈中。
单实例模式:这是一种加强的singleTask模式,他除了具有singleTask模式的所有特性之外,还加强了一点,在这种模式下的Activity只能单独处于一个任务栈中。如果ActivityA是singleInstance模式,当A启动后,系统会为它新建一个任务栈。然后A独自在这个任务栈中
在singleTask模式中提到了任务栈,任务栈由参数TaskAffinity决定,这个参数标识了一个Activity所需要的任务栈的名字。默认情况下,所有Activity所需的任务栈名字为应用的包名。
<activity android:name=".MainActivity"
android:screenOrientation="portrait"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
intent-filter>
activity>
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
Activity的启动分为显示和隐式调用。隐式调用需要匹配目标组件的IntentFilter组件的所设的过滤信息,如果不匹配将无法启动目标Activity。IntentFilter中的过滤信息包括,action,category,data。
例:
一个过滤列表可以有多个action,cotegory,data,所有的action,cotegory,data分别构成不同类别,同一类别可以共同约束当前类别的匹配过程。只有一个Intent同时可以匹配action类别,category类别,data类别,才算完全匹配,只有完全匹配才能成功启动目标Activity。另外,一个Activity中可以有多个intent-filter,一个Intent只要能够匹配任意一组intent-filter即可成功启动相应的Activity。
action的匹配规则: intent中的action必须能够和过滤规则中的action匹配,即和字符串值完全一样。一个过滤规则中可以有多个action,那么只要Intent中的action能够和过滤规则中的任意一组相同即匹配成功
注意的点:
category的匹配规则 :如果Intent中如果含有category,那么所有的category都必须和过滤规则中的其中一个category相同。即,如果Intent中如果出现了category,不管有几个category,对于每个category都必须是过来规则中存在的。
注意的点
1. Intent中可以不指定category,不指定时,也可以匹配成功,
2. 系统在调用startActivity或者StartActivityForResult会默认为Intent加上”abdroid.intent.category.DEEAULT”这个category。所以为了我们的Activity能够隐式调用Activity,就必须在intent-filter中指定“abdroid.intent.category.DEEAULT”指定category。
data的语法
"string"
android:host = "string"
android:port = "string"
android:path = "string"
android:pathPattern = "string"
android:pathPrefix="string"
android:mimeTYpe = "string"/>
data由两部分组成,mimeType和URI。
mimeType指3媒体类型,比如image/jpeg,video等等
URI:
data的匹配规则
data的匹配规则和action类似。它也要求Intent中必须含有data数据,并且data数据能够完全匹配过滤规则中的某一个data。
判断是否有Activity能够响应我们的intent有两种方法:PackageManager的resolveActivity方法或者Intent的resolvActivity方法,如果找不到匹配的Activity就会返回null。
《Android艺术开发探索》
《第一行代码》