生命周期和启动模式
#生命周期
##正常的生命周期
从启动到销毁的完整生命周期:oncreate->onstart->onresume->onpause->onstop->ondestory
oncreate与ondestory对应,onstart与onstop对应,onresume与onpause对应,对应的分析角度不同,oncreate与ondestory从界面的创建与销毁的角度看,onstart与onstop从是否可见的角度看,onresume与onpause从是否前台的角度看。
前台切换到后台执行如下:onpuase->onstop
后台切换到前台执行如下:onrestart->onstart->onresume
##异常的生命周期
如下情况可能导致异常的生命周期:1.系统配置更改,比如语言,位置信息,横竖屏方向。
Activity在异常结束的时候会调用onsaveinstatnce,存储相关信息,在恢复的时候传递bundle对象到自身,这个在onstop之前,和onpause没有时序关系。
Activity从异常恢复的时候会调用onrestoreinstance,如果bundle对象不为空,则恢复bundle中的信息,这个在onstart之后调用
横竖屏切换执行如下:onpause->onSaveInstanceState->onstop->ondestory->oncreate->onstart->onresotreInstanceState->onresume
#Activity启动模式
Android通过任务栈对Activity进行管理
##launchmode
- 1.standard 每次创建一个实例,不管任务栈中是否有该Activity的实例,创建后,该Activity运行在启动它的Activity所在任务栈中,用Application启动activity会报错,因为Application没有任务栈,这时候需要add flag new task,这样为Activity新建一个任务栈
- 2.singleTop 每次创建实例的时候,如果栈顶有该Activity的实例,调用newIntent,不进行创建,否则创建
- 3.singleTask 每次创建实例的时候,如果栈内有该Activity的实例,调用newIntent,不进行创建,同时该Activity所在栈内之上的Activity都会进行出栈操作,否则创建
- 4.singleInstance 单实例模式,和singletask具有相同特性,同时启动模式标记为singleinstance的Activity会单独运行在一个任务栈中
Activity的taskAffinity属性指定了希望进入的Task。如果Activity没有指明taskAffinity,那其taskaffinity等于Application指明的taskAffinity,如果 Application也没有指明,那么该taskAffinity的值就等于包名。而Task也有自己的affinity属性,它的值等于它的根 Activity的taskAffinity的值。
所以在启动Activity的时候,没有指定taskAffinity,则默认放入该Application的任务栈中,如果指定了taskaffinity,则在启动模式为singletask的时候先查找任务栈中是否有相同taskaffinity,如果没有则新建任务栈并放进去,有则放入该任务栈。
##设置launchmode
- 1.在AndroidManifest.xml中进行定义
- 2.在代码中进行设置 intent.addflag(Intent.flag)
- 3.如果xml和code中都添加了flag,优先级上code为高优先级,但是code中addflag的缺点是不能指定为singleinstance,xml的缺点是不能为Activity添加FLAG_ACTIVITY_CLEAR_TOP标识
- 1.action action是字符串,匹配时区分大小写,中间用 . 隔开。intent中action必须指定,如果不指定则匹配失败
- 2.category,category如果没有指定,则加载默认category,default,如果存在category,则必须匹配成功
- 3.data data匹配与action类似
<data
android:scheme="string" //scheme:URI的模式,比如http、file、content等,默认值是 file 。
android:host="string" //host:URI的主机名
android:port="string" //port:URI的端口号
android:path="string"
android:pathPattern="string"
android:pathPrefix="string" //path、pathPattern和pathPrefix:这三个参数描述路径信息。
android:mimeType="string"/> //mimeType是指媒体类型,比如image/jpeg、audio/mpeg4-generic和video/等,可以表示图片、文本、视频等不同的媒体格式。
由上面可以看出Intent中的data由两部分组成:URI,mimeType。
URI的结构: <scheme>://<host>:<port>/[<path>|<pathPrefix>|<pathPattern>]
举例如下:
content://com.example.project:200/folder/subfolder/etc
http://www.baidu.com:80/search/info
Intent指定完整data时,必须调用 setDataAndType 方法, 因为setData 和 setType 会清除另一方的值。
##隐式调用异常防范
在隐式调用的时候如果没有找到目标Activity却startActivity的时候会抛出ActivityNotFoundException,所以在StartActivity之前需要Check下是否存在目标Activity。
- PackageManager 的resovleActivity
- Intent的resolveActivity