首先第一步,我们最熟悉的android生命周期图如下:
从上图可以知道,android正常生命周期有如下规律总结
1:启动一个正常的acitivity时候,生命周期总会执行oncreate()->onstart()->onresume()
2:当我们将一个正在打开的activity切换到桌面的时候,总会执行:onpause()->onstop,(在这里注意,若是该activity采用的是透明的主题,将不会执行onstop()函数)
3:当我们重新返回刚才被返回桌面或者跳转的activity时候,会执行:onrestart()->onstart()->onresume();
4:当我们推出程序的时候,该activity执行的是:onpause()->onstop()->ondestory();
5:若是一个activity已经被回收销毁,你再重新打开的时候,跟打开一个新的从来没打开过的activity的生命周期一样:oncreate()->onstart()-onresume();
6:假设有一种情况,有两个activity,一个是activityA,一个是activityB,当activityA打开启动activityB,这时候生命周期是:activityA.onpause()->activityB.oncreate()->activityB.onstart()->activityB.onresume()->activityA.onstop(),
7:从上面那条规律可以得知,上一个activity的opause()方法会在下一个调用的activity之前被调用,所以为了程序的流畅性,不要在onpause()方法中执行重量级或者耗时操作,否则会延迟下一个activity的启动
8:activity若是遭遇一些情况而被迫关闭销毁,那么会在销毁之前调用onsaveinstancestate()方法,这个方法用来保存一些信息,保存的原理是activity将要保存的需求通知上层的view,然后上层的view将保存需求分发给页面每一个组件,让每一个组件保存自己负责的信息,比如页面有edittext输入框的,edittext本身就有onsaveinstancestate()方法,你可以看看底层,它这个方法就是保存当前输入的信息,其他组件同样,所以在这个activity被重新启动的时候,该activity的生命周期会是oncreate()->onrestoreinstancestate()方法,该onsaveinstancestate()会将各个组件保存的信息重新赋值给组件
二,activity的优先级分为三级
第一级:前台activity,就是当前正在显示的那个activity
第二级:可见activity,就是可见,但是不可操作activity,比如弹出了一个dialog的activity,这时候的activity虽然可以看到,但是你触摸操作不到它
第三极:后台activity,就是已经不能看见的activity,一些被关掉的activity就是这种情况
当内存不足的时候,系统会杀死优先级较低的activity来释放内存,所以杀死顺序是:后台activity>可见activity>前台activity
三,activity的四种启动模式
1,standard模式,这是默认模式,假如一个activity被设置为standard模式,那么每一次启动该activity都会在栈里面创建一个新的activity,不管栈里面有没有存在这个activity的实例,反正一定要创建一个新的,就是这么土豪
2,singletop模式,也就是栈顶复用模式,原理就是,假如要启动的这个activity,其实已经有一个这个activity的实例位于当前栈的栈顶了,那么程序将不会再创建该activity,而是重新启动栈顶的该activity实例而已,并且已经这个实例本身已经存在,所以启动的时候不会执行oncreate()和onstart()方法
3,singletask,假如一个activity模式为singletask,那么当想要启动这个activity,会先检查在当前程序中有没有这个activity想要的任务栈,若是没有,便马上创建一个新的任务栈,然后创建这个activity实例放入栈中,若是有,那么检查这个任务栈中是否已经存在这个activity的实例,若是有,就将这个activity的实例提到栈顶,若是没有,便创建新的activity放入栈顶
4,singleinstacne模式,若是一个activity设置为这个模式,那么不管怎么样,这个activity只能独自存在一个任务栈中,若是没有这个任务栈就会创建任务栈然后将这个activity放进去,要是已经有这个任务栈,还有这个activity,那么就会复用启动这个activity
在这里在说一种特别情况,当假设有两个这样的任务栈,前台任务栈A,B,还有包括启动模式都为singletask的activityC,D的后台任务栈
当我们在activityB中启动activityD的时候,其实是将整个后台任务栈activityC和activityD都移动到前台任务栈中,但若是只是在activityB中启动了activityC而已,那么移动的图如下
四 任务栈属性taskAffinity
一般来说,一个activity的所属任务栈都是当前的包名,但若是你想给某个activity指定一个特定的任务栈时候,可以在activity的配置参数中增加一个taskAffinity属性,代表这个activity所属的任务栈
在这里有一点需要注意,这个taskAffinity属性主要与singletask或者allowtaskReparenting配合使用,当一个activity设置为singletask模式和指定了taskAffinity之后,它在被启动之后会运行在这个taskAffinity指定的任务栈中,并且由这个activity启动的activity同样也会运行在这个任务栈中
而allowTaskReparenting属性就比较有趣了,假设有两个应用A和B,若是B中有一个activityC,他的allowTaskReparenting属性设置为true,那么当A去启动B中的这个activityC的时候,本来两个应用有各自的任务栈,不会有交集,但是在这种情况下,activityC却会被加入到A的任务栈中,假设这时候你按了返回键,然后再点击A的应用图标,那么显示的是应用B的activityc界面,这种情况可以参照微信分享界面,别的应用分享到微信的时候也会打开一个微信的界面
五 intent的隐式调用
intent可分为显示调用和隐式调用
显示调用,就是写死要调用的组件,大致,如下:
Intent intent = new Intent(mContext, XXActivity.class);
startActivity(intent);
而隐式调用的话,则是这个intent对系统所有应用发布调用广播,并不关心是自己应用还是别人应用接收到这个intent,反正只要能匹配到它的匹配规则的activity都会被调用到隐式调用匹配规则主要看三个参数:action,category,data
这些参数都在配置文件中配置,配置在intent-filter中,如下
而某个intent若想调用上面的activity,则必须设置好这些参数,如下
//创建一个隐式的 Intent 对象:Category 类别
Intent intent = new Intent();
intent.setAction("customer_action_here");
//添加与清单中相同的自定义category
intent.addCategory("customer_category_here");
startActivity(intent);