Android-启动模式task-lunchmodle-intent flag 总结

总结:

  • 同一task内的activity可以是来自不同进程的activity
  • 栈内的activity不会重新排序,只能push或者pop
  • standard模式允许多实例,可以在不同的task
  • singleTask的activity只会存在一个实例
  • singleTask的activity如果设置了独立的taskAffinity属性值,启动时就会在新的task中,否则会在已有task中
  • singleTask的activity启动时,它会在目标task(新的task或者已有task)中查看是否已经存在相应的activity实例,如果存在,就会把位于这个activity实例上面的activity全部销毁(pop, destroy)掉,即最终这个activity实例会位于任务的堆栈顶端中

task

task是一个从用户角度出发的概念,它是一些activity的组合,它们组合起来是为了让用户完成某一件工作(或者说操作)。

task内的activity们以栈的形式组织起来,也就是back stack了。栈内的activity不会重新排序,只能push或者pop。栈内的activity可以来自不同的app,因此可以是运行在不同的进程,但是它们都属于同一个task内。

安卓系统是实时多task系统,用户可以随意在多个task之间切换。当一个task的栈内所有activity都pop之后,task也就销毁了。有时系统为了回收内存,会销毁activity,但是task不会销毁。

activity在manifest中有launchMode选项,可以配置其启动的模式。标准模式下,允许一个activity同时存在多个实例,既可以在同一个task,也可以在不同task。manifest可以指定launchMode,intent可以指定intent flag,前者供被启动者使用,后者供启动者使用,同时使用时后者会覆盖前者。

launchMode

  • standard,默认模式,允许多实例
  • singleTop,相比于standard,有新的启动请求时,只有在目标activity处于当前栈顶时,才会调用onNewIntent()而不创建新实例,其他情况都和standard一致
  • singleTask,(这段摘自老罗的博客)设置了”singleTask”启动模式的Activity,它在启动的时候,会先在系统中查找属性值affinity等于它的属性值taskAffinity的任务存在;如果存在这样的任务,它就会在这个任务中启动,否则就会在新任务中启动。因此,如果我们想要设置了”singleTask”启动模式的Activity在新的任务中启动,就要为它设置一个独立的taskAffinity属性值。如果设置了”singleTask”启动模式的Activity不是在新的任务中启动时,它会在已有的任务中查看是否已经存在相应的Activity实例,如果存在,就会把位于这个Activity实例上面的Activity全部结束掉,即最终这个Activity实例会位于任务的堆栈顶端中。
  • singleInstance,和singleTask相比,不同点在于singleInstance activity所在的task只会有这一个activity
  • 返回导航:singleTask和singleInstance启动的activity,尽管可能不在同一个task,但是仍然会回到原来的activity;但是singleTask可能会存在back
    stack“拼接”的情况

launchMode验证测试

主要测试的是singleTask这一属性,其他的文档描述都比较清楚,也不容易产生误解。两组实验,不设置taskAffinity和设置taskAffinity时,singleTask的行为。对比两者“最近任务”,dumpsys,logcat,返回导航的差异。

测试1

不设置taskAffinity,MainActivity -> SingleTaskFirstActivity -> SimpleActivity -> SingleTaskSecondActivity -> 选择图片Intent,再一路返回。

最近任务内只能看到一个TaskDemo的任务,dumpsys的结果如下:

所有的activity均在同一个task内,验证了老罗的结论。另外注意标红的两处,它们的ProcessRecord对象不同,ImageGallery和SingleTaskActivity处于不同的进程,也验证了前文所述“可以运行在不同的进程”。

logcat日志如下:

一路返回依次回到SingleTaskSecondActivity, SimpleActivity, SingleTaskFirstActivity,MainActivity, 桌面。

测试2

设置SingleTaskFirstActivity的taskAffinity为单独的值,MainActivity -> SingleTaskFirstActivity。

通过最近任务可以看到,有了两个TaskDemo的任务。而dumpsys结果如下:

可以看到,MainActivity和SingleTaskFirstActivity运行在了两个不同的task里面(栈底为MainActivity的t225, 栈底为SingleTaskFirstActivity的t226),但是他们仍属于同一进程。

我们接着启动SimpleActivity,再通过最近任务切换回t225,并且也启动SimpleActivity,这时通过dumpsys结果如下:

SimpleActivity同时存在两个实例,他们的hashCode是不同的,目前处于resumed状态的是在t225中的实例。

而通过查看logcat:

我们同样发现SimpleActivity被创建了两个实例。

此时我们通过最近任务切换回t226,并在此启动SingleTaskSecondActivity,查看dumpsys,然后再切换回t225也启动SingleTaskSecondActivity,查看dumpsys和logcat:

我们可以看到尽管第一次启动SingleTaskSecondActivity是在t226,但是SingleTaskSecondActivity实例却运行在t225中,为什么呢?因为SingleTaskSecondActivity并没有设置taskAffinity属性,所以它和MainActivity将会运行在同一个task中!和老罗的分析一致。而第二次启动时,并未创建新的SingleTaskSecondActivity实例,而是调用了它的onNewIntent方法,和文档描述一致。

现在我们测试一下返回导航,依次按下返回键,观察每次回到的activity,以及每次dumpsys的结果,以及logcat的结果:

第一次回到了t225的SimpleActivity,dumpsys:

第二次回到了t225的MainActivity,dumpsys:

第三次回到了t226的SimpleActivity,dumpsys:

第四次回到了t226的SingleTaskFirstActivity,dumpsys:

最后一次返回就回到了桌面。

logcat日志如下:

从上面的返回路径来看,确实验证了developer文档上关于back stack“拼接”的情况的描述,即:并不是按照most
recent first的顺序返回的,而是优先把一个task的back stack(t225) pop完毕之后,再pop下一个task的back stack(t226)。

测试3

基于测试2的版本,MainActivity -> SingleTaskFirstActivity -> SimpleActivity,再切换回MainActivity,再启动SingleTaskFirstActivity。

查看最近任务,仍然有两个task,但是查看dumpsys以及logcat:

我们可以看到,第一次启动的SimpleActivity就被pop(destroy)了,从而把未在栈顶的SingleTaskFirstActivity提到了栈顶。这也验证了back stack内的activity不会重新排序,最会pop和push的事实。

Intent flag

只要搞清楚了launchMode中容易产生误解的地方,对于intent flag来说,只需要记住一点即可:intent flag可以覆盖launchMode的设置。为了避免内容过于冗长,本文就不对intent flag进行详细的测试分析了。

总结

  • 同一task内的activity可以是来自不同进程的activity
  • 栈内的activity不会重新排序,只能push或者pop
  • standard模式允许多实例,可以在不同的task
  • singleTask的activity只会存在一个实例
  • singleTask的activity如果设置了独立的taskAffinity属性值,启动时就会在新的task中,否则会在已有task中
  • singleTask的activity启动时,它会在目标task(新的task或者已有task)中查看是否已经存在相应的activity实例,如果存在,就会把位于这个activity实例上面的activity全部销毁(pop, destroy)掉,即最终这个activity实例会位于任务的堆栈顶端中
时间: 2024-10-22 02:53:44

Android-启动模式task-lunchmodle-intent flag 总结的相关文章

Android Activity 的四种启动模式 lunchMode 和 Intent.setFlags();singleTask的两种启动方式。

Android Activity 的四种启动模式 lunchMode 和 Intent.setFlags(); 一.Android Activity 四种启动模式 lunchMode 在Manifest 配置文件中的属性如下: (1) android:launchMode="standard" (2)android:launchMode="singleTop" (3)android:launchMode="singleTask" (4)andro

Android -- 启动模式

Android的启动模式分为四种: standard 模式启动模式,每次激活Activity时都会创建Activity,并放入任务栈中. singleTop 如果在任务的栈顶正好存在该Activity的实例, 就重用该实例,否者就会创建新的实例并放入栈顶(即使栈中已经存在该Activity实例,只要不在栈顶,都会创建实例). singleTask 如果在栈中已经有该Activity的实例,就重用该实例(会调用实例的onNewIntent()).重用时,会让该实例回到栈顶,因此在它上面的实例将会被

Android Activity 的四种启动模式 lunchMode 和 Intent.setFlags();

一.Android Activity 四种启动模式 lunchMode 在Manifest 配置文件中的属性如下: (1) android:launchMode="standard" (2)android:launchMode="singleTop" (3)android:launchMode="singleTask" (4)android:launchMode="singleInstance" 二.说明: Android 中

Android启动模式以及IntentFilter匹配规则

一.Android的LaunchMode 共有四种启动模式 1.standard 标准启动模式,Activity的默认启动模式.Activity的每次启动都创建新的示例 2.singleTop 栈顶复用模式,当启动的Activity处于栈顶时,不再创建新的活动实例.将回调onNewIntent方法. 3.singleTask 栈内复用模式,当启动的Activity在一个栈中存在实例,不再创建新的实例,弹出在其之上的所有实例将其置于栈顶.同样会回调onNewIntent方法. 4.singleIn

android启动模式2

Android中的启动模式(下) 在这篇文章中,我会继续跟大家分享有关于Android中启动模式的相关知识.当然,如果对这个启动模式还不完全了解或者没有听过的话,可以先看看我之前写的有关于这个知识点的入门篇Android的启动模式(上).好了,言归正传,在上一篇已经介绍过,activity在栈中默认不能重排,因此,应用中的一个activity可能被多次实例化并且压入同一个栈中,如图所示: 如果此时使用back键返回,activity的每个实例都将会按照打开的顺序重新出现.这势必会导致用户生体验效

Android启动模式launchMode

在Android里,有4种Activity的启动模式并分别介绍下: standard singleTop singleTask singleInstance AndroidManifest.xml配置android:launchMode属性 1.standard: 默认启动模式. 每次都会创建一个实例,每个任务栈里面都可以使用. 2.singleTop: 系统会按照singleTop启动模式处理跳转行为.跳转时系统会先在栈结构寻找是否有一个Activity实例正位于栈顶,如果有则不在生成新的,而

Android启动模式(三种)

1,标准启动模式 通过任务栈,每点一次button,将每一个实例都压入,然后点返回键时候,就弹出之前压入的实例. 测试代码:通过创建一个button和textView来显示本身的TastId和实例的ID 1 public class MainActivity extends AppCompatActivity { 2 3 private TextView tv; 4 @Override 5 protected void onCreate(Bundle savedInstanceState) {

Android启动模式之singleinstance的坑

前言 在实际应用中,使用singleinstance启动模式时,会遇到一些奇奇怪怪的问题.Android有四种启动模式,分别是standard,singleTop,singleTask,singleInstance.下面分别简单的介绍下这四种启动模式的作用. standard Android 默认的一种启动模式.不需要为activity设置launchMode.这种启动模式简单的来说就是当你startActivity的时候,他就创建一个. singleTop 这种模式模式从字面意思就能看得出来,

Android -- 启动模式(标准启动模式)

我们先来运行一段程序,看看效果. 看下图,taskID=15,实例*89270结尾 再点击刷新按钮,如下图,发现taskID没有变,但是实例变了*bead0 在刷新一次,同上,实例变成*d0348. 下面,我们点击返回按钮,看下图 再点击返回按钮 看完上面一组操作,我们是否发现,刷新后taskid没有变化,但是实例在不断变化,当点击返回按钮时,返回的是最近生成的一个实例,这里有一个栈的概念,先进栈的实例后出(任务栈),也就是先进后出,后进先出的原理,这个就是标准启动模式的原理. 配置启动模式代码

Android -- 启动模式(singleTop启动模式)

了解了标准的启动模式,是使用任务栈,先进后出,后进先出的模式进行启动的,下面我们来看另外一个singleTop启动模式. 1.我们来看图,这个页面我增加了2个按钮,分表转A页面和B页面,先来看A,我们的taskid=18,实例=*f648 2.点击[跳转A页面Activity],发现了吗,没有变化,实例还是*f648 3.我们点击[跳转B页面Activity],taskid=18,实例=*54f0,新生成了个实例. 4.我们再点击[跳转A页面Activity],实例变了,和我们第2步实例不一样了