1.问题描述
今天碰到了一个问题,当一个Activity的启动模式为SingleTask的时候,Activity间进行跳转的时候,在该Activity的onCreate()方法里接收不到Bundle携带过来的值,通过这个小问题也让我明白了学习启动模式的重要性。
在解决这个问题之前,我们先来看一种情况,假设现在有ABCDE五个ActivIty,只有B的启动模式是singleTask,其余Activty是标准模式,Activity跳转的顺序是ABCDEAB,问现在栈中还有那几个Activity,知道singleTask原理的小伙伴们很容易知答案是A和B。
2.找原因
我们先来对比一下,standard标准模式和 singleTask 栈内复用模式:
1.如果ABCDE这五个Activity都是标准启动模式,那依次执行完跳转Activity:ABCDEAB,栈内的情况是这样的:
情形1标准启动模式也是系统默认的启动模式,每启动一个Activity,都会重新创建一个实例,不管这个实例是否存在,并且我们知道任务栈是"先进后出的",所以先进栈的A位于栈底,最后一个Activity B位于栈顶。
2.当B Acticity的启动模式是singleTask 栈内复用模式时候,栈内的情况是这样的:
情形2(a)因为B 的实例在栈内存在,所以再次启动的时候,就不会重新创建实例了,所以B 回到栈顶,并且B 上面的 实例会被移出栈,最终任务栈内的情况是这样的:
情形2(b)回到我开头说的那个问题,启动一个 启动模式为 SingleTask 的Activity,为什么会在onCreate()方法里,拿不到Bundle传递的值?
原因也很简单,假设在任务栈中存在该Activity的实例,再次启动的时候,也就不会重新去创建它的实例,onCreate方法并没有执行,也就获取不到Bundle传递过来的值。此时,我们需要重写 onNewIntent()方法,系统会回调其onNewIntent方法,并将 onNewIntent 接收的 intent设置给 Activity。之后,我们可以在 onStart()方法中接收Bundle传递过来的值。
假设任务栈内不存在该Activity的实例,就会重新创建,其生命周期方法onCreate(),onStart(),onResume() 都会正常执行。
3.感悟
Activity作为四大组件之一,其重要性不言而喻,除了生命周期之外,它的启动模式也是一个重点和难点,找工作面试被问的概率还是很大,当然更重要的是,我们日常开发工作的时候,为了满足某些项目的特殊需求,就必须使用到Activity的启动模式,所以我们必须要掌握其四种启动模式。
网友评论