创建状态:已经从内存中生成了。(oncreate(进) onDestroy(出))
可见状态:如果前台Activity是有一定透明度或不是全屏的,就可以看到了,但不在前台。(onStart(进) onStop(出))
前台状态:在最上层可以直接交互。(onResum(进) onPause(出))
Activity正常生命周期情况:
1.A再次可见会执行onRestart();
2.A->B时,如果B是有一定透明度或不是全屏的,A可见,A生命周期只执行onPause不执行onStop。
(如果A上弹出Dialog时,A的生命周期没有变化)
3.A->B时,如果B不透明且全屏,A生命周期只执行onPause和onStop
4.A->B时,如果B不透明且全屏,A和B的生命周期顺序是A.onPause,B.onCreate B.onStart B.onResume A.onStop。(在A的 onPause不要执行费时的东西,因为会影响B的显示速度)
Activity异常生命周期情况:
Activity异常结束再恢复会多执行另外一对函数onSaveInstanceState onRestoreInstanceState。
---------onstart后--------------------------------------
onRestoreInstanceState是在onStart之后,在onResume之前(只有从异常恢复时才执行)。
onSaveInstanceState在onStop之前,它和onPause没有前后关系。(跳转或者home此函数都会执行)
---------onStop前-------------------------------------
1.A不在前台因内存不足被意外回收后,再次回到A时会执行onCreate(savedInstanceState),这时savedInstanceState不等于null(正常状态下savedInstanceState==null),并且还会执行onRestoreInstanceState(savedInstanceState)(正常状态下不会被执行)。
2.当配置改变时会引起当前Activity销毁重建算是Activity异常终止。例如竖横屏切换时。
竖屏-->横屏会重建一次Activity:
onSaveInstanceState-->onPause()-->onStop()-->onDestroy()--|-->onCreate()--onStart()-->onRestoreInstanceState()-->onResume()i
横屏-->竖屏会重建两次Activity:
onSaveInstanceState-->onPause()-->onStop()-->onDestroy()--|-->onCreate()--onStart()-->onRestoreInstanceState()-->onResume()-->onSaveInstanceState-->onPause()-->onStop()-->onDestroy()--|-->onCreate()--onStart()-->onRestoreInstanceState()-->onResume()
如果不想让某一项配置的变化引起Activity的变化,可以给该Activity的android:configChanges属性赋该项的值,过滤掉此项。过滤掉此项后不会引起Activity重建但会回调activity的onConfigurationChanged方法在在这个方法里可以做其他处理。
这些配置项可以是:
orentation 屏幕方向发生改变
keyboardHidden 键盘可访问性发生改变
screenSize 屏幕大小改变时(方向发生改变会引起该项变化)
locale 本地位置发生改变时。
------------------------------------------------------------------------------------------------------------------------
启动模式
在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作。在Android中Activity的启动模式决定了Activity的启动运行方式。
1、标准模式(standard):ABC->ABCC 每次激活Activity时都会创建Activity,并放入任务栈中,永远不会调用onNewIntent()。
例如A启动A,A再接着启动A,A继续启动A,然后再分别出栈
2、栈顶复用模式(singleTop):ABC->ABC如果在任务的栈顶正好存在该Activity的实例, 就重用该实例,并调用其onNewIntent(),否者就会创建新的实例并放入栈顶(即使栈中已经存在该Activity实例,只要不在栈顶,都会创建实例,而不会调用onNewIntent(),此时就跟standard模式一样)。
3、栈内复用模式(singleTask):ABCDF->ABC如果在栈中已经有该Activity的实例,就重用该实例(会调用实例的onNewIntent())。重用时,会让该实例回到栈顶,因此在它上面的实例将会被移除栈。如果栈中不存在该实例,将会创建新的实例放入栈中(此时不会调用onNewIntent())。
4、单例复用模式:AB->AB: C 在一个新栈中创建该Activity实例,并让多个应用共享该栈中的该Activity实例。一旦该模式的Activity的实例存在于某个栈中,任何应用再激活改Activity时都会重用该栈中的实例,其效果相当于多个应用程序共享一个应用,不管谁激活该Activity都会进入同一个应用中。
一个应用的Activity供多种方式调用启动的情况,多个调用希望只有一个Activity的实例存在,这就需要Activity的onNewIntent(Intent intent)方法了。只要在Activity中加入自己的onNewIntent(intent)的实现加上Manifest中对Activity设置lanuchMode=“singleTask”就可以。
onNewIntent()非常好用,Activity第一次启动的时候执行onCreate()---->onStart()---->onResume()等后续生命周期函数,也就时说第一次启动Activity并不会执行到onNewIntent(). 而后面如果再有想启动Activity的时候,那就是执行onNewIntent()---->onResart()------>onStart()----->onResume(). 如果android系统由于内存不足把已存在Activity释放掉了,那么再次调用的时候会重新启动Activity即执行onCreate()---->onStart()---->onResume()等。
当调用到onNewIntent(intent)的时候,需要在onNewIntent() 中使用setIntent(intent)赋值给Activity的Intent.否则,后续的getIntent()都是得到老的Intent。
任务栈:保存Activity的顺序的栈,具有相同TaskAffinity(任务密切关系)属性Acivity会在同一个任务栈里。同一个应用里的所有Activity默认有相同的TaskAffinity,在同一个任务栈里。如果Activity的allowTaskReparenting(允许任务重定父级)属性为真且属于应用B时,A应用启动了该Activity在A的任务栈里,如果这时启动B应用,该Activity会回到B应用的任务栈里。
-----------------------------------------------------------------------------------------------------
Intent
intentFilter匹配规则:
如果一个Activity接受隐式调用,intentfilter中action必须有,category是必须有且这个android.intent.category.DEFAULT必须有,data不是是必须的。”,
action过滤规则:intent只有一个action,Intentfilter可以有多个要与其中一个action相同(action相同是指action字符串相同),则匹配,否则不匹配。(如果要匹配,intentfilter中有action,intent必须要有action)
category过滤规则:intent可以增加category,intent所有的category必须在Intentfilter中找到对应(category相同是指category字符串相同)。否则不匹配。(intent可以不手动设置category,intent中默认有一个android.intent.category.DEFAULT,Actiivity如果接受隐式调用intentfilter必须有android.intent.category.DEFAULT)
data过滤规则:intent只能设置一个data,和Intentfilter中其中一个data匹配(data匹配是指目标data中所用字段源中都有且相同),则匹配,否则不匹配。(如果要匹配,intentfilter中有data,则intent必须设置data)
data结构:
<data
android:scheme="d"
android:host="d"
android:port="90"
android:path="/dd/dd"
android:pathPattern="//d" //路径模式
android:pathPrefix="/dd" //路径前缀
android:mimeType="image/*"/>
data有两部分组成uri和mimeType
<scheme>://<host>:<port>/[<pathPrefix>|<path>|<pathPattern>]
scheme:uri的模式,比如HTTP file等。scheme必须有。
host:uri主机名
port:端口号
path 是全路径,如:http://example.com/blog/abc.html,这里将 path 设置为 /blog/abc.html 才能够进行匹配;
pathPatter也是路径只是里面的字符串是正则表达式。
pathPrefix 用来匹配路径的开头部分,拿上面的 Uri 来说,这里将 pathPrefix 设置为 /blog 就能进行匹配了;
mimeType:媒体类型,例如 image/jpeg、video/*
setType 调用后设置 mimeType,然后将 data 置为 null;
setData 调用后设置 data,然后将 mimeType 置为 null;
setDataAndType 调用后才会同时设置 data 与 mimeType。
intent 的
resolveActivity如果没有匹配的activity返回null
packageManager的
resolveActivity如果没有匹配的activity返回null
queryIntentActivities返回匹配的所有Activity信息
intent的flag:
flag有些事系统使用的,不需要用户。
还有些其他的flag
有些flag是启动activit,给intent设置flag启动activity。
FLAG_ACTIVITY_SINGLE_TOP
达到activity栈顶复用。
FLAG_ACTIVITY_NEW_TASK
FLAG_ACTIVITY_CLEAR_TOP
一般一起使用达到activity的栈内复用