前言
Android中的启动模式和任务栈想必大家都已经很熟悉了,因最近做项目过程中正好遇到这个问题,在这里顺便写篇文章加深下记忆.
任务栈
启动一个android应用程序时,系统会为它创建一个存放activity的任务栈。默认启动activity会放在一个task中,并且遵循先进后出的原则。一个Android应用程序中通常会有多个activity,新启动的Activity会被压入启动它的那个Activity的栈中。栈是一个先进后出的线性表,默认情况下,当一个Activity启动了另一个Activity的时候,新启动的Activity就会置于任务栈的顶端,并处于活动状态。
activity启动模式
activity启动的模式有Standard(标准模式,默认),SingleTop(栈顶复用模式),SingleTask(栈内复用模式),SingleInstance(单实例模式)
Standard默认模式,每次都会创建一个新的实例。在这种模式下,可以有多个相同的实例。
SingleTop栈顶复用模式,如果启动的activity在任务栈的顶部已经存在,就不会创建新的实例而是复用它。
SingleTask栈内复用模式, activity在任务栈里面只存在一个实例。如果要启动的activity在任务栈里面已经存在,就不会创建新的activity,而是复用这个已经存在的activity,并且清空这个activity任务栈上面所有的activity。
SingleInstance单一实例模式,整个系统里面只有一个实例存在,它会运行在自己独立的任务栈里面,并且任务栈里面只有他一个实例存在。
遇到问题
项目中有个功能,接收到推送会播放相应的语音.测试那边报一个BUG会时不时出现播放多条语音的情况.咋一看这个BUG就应该是服务器的问题呀,终端不会产生消息也不会存消息是不.而且打断点测试确实进入了N次接收消息的function,这也是为什么一开始不能排查原因的原因.经过与后端人员测试,别个说只发了一条.一直是抱着怀疑的态度.那么语音到底是从哪来的?
后面实在没辙,不打断点,只打日志测试.出乎意料,接收消息的function只打印了一次日志,但是播放语音的function打印了多次.停顿了几秒钟,大概是知道问题在哪里了.因为播放语音功能在activity里面,所以是这个activity有多个实例?
解决问题
情况确实是这样的,因为页面切换回到播放语音的activity时没有设置启动方式,所以默认是standard,也就是每次都重新启动了一个新的实例。那么解决问题的第一步是要保证播放语音的activity只有一个实例,用singletask果然解决了问题。
感想
深入理解activity的启动模式和任务栈对我们平时开发其实是很有帮忙的,根据项目的具体需求使用不同的启动方式是有必要的,合理地使用启动方式尽量让任务栈的activity没有重复,该出栈时让它们出栈,这样也能节约一部分内存。