认识Activity的LaunchMode

认识Activity的LaunchMode

从刚接触Android开始我就了解到了launchMode的四种启动模式,但是我没有去深如了解,哪怕再深入一点点。

这段时间 在准备 面试 复习之前学习的知识我也感觉 要准备的很多。

我们要了解LaunchMode就要了解Activity的回退栈,要明白LaunchMode是为谁提供的?

我们先来复习一下Activity的LaunchMode:

  1. standard: 标准启动模式,每次打开activity都会在当前app回退栈的栈顶创建activity示例,并显示。
  2. singleTop:当activity位于栈顶则再次打开当前activity只会调用onNewIntent()方法,不会调用onCreate()等生命周期回调
  3. singleTask:全局单例模式,Task中只会有这一个实例。
  4. singleInstance:在singleInstance的基础上的进一步加强。会单独为该Activity创建一个Task。

由launchMode延伸出来的知识点:

  • startActivity()时Intent.FLAG_Activity_XXX

    • FLAG_ACTIVITY_NEW_TASK
    • FLAG_ACTIVITY_SINGLE_TOP
    • FLAG_ACTIVITY_SINGLE_TOP
    • FLAG_ACTIVITY_CLEAR_TOP
    • and so on
  • :taskAffinity属性

  • :allowTaskReparenting

  • :clearTaskOnLaunch

  • Activity的回退栈

  • 最近任务列表的切换

当我们从Home点击应用图标打开一个应用的时候都发生了什么?

我们会创建那个IntentFilter标签带有Main和Launcher的activity并把它放在该app的任务栈的栈底。用户可以方便的通过最近任务列表切换Task,当我们打开了一个应用使用了一会,如果该应用没有重写onBackPressed()方法,则用户返回时就会从Task中finish()掉一个activity,当我们把这个应用的acivity全部都finish()掉这个Task就会被清除,但是我们仍可以从最近任务列表中看到这个app的Task,这是Android为了方便用户切换刚刚使用的应用(其实应该叫方便用户重新启动刚刚关闭掉的app)。
当在使用App A的时候打开了app B的activity,这个时候b 的activity就会直接在App A Task上创建示例。
但是当app B的activity的launchMode设置为SingleTask的时候或者SingleInstance的时候,被启动的activity只会放在自己的Task之中。然后让包含app B要启动那个的Task压在app A 的Task上边(这时候切换activity的动画是应用见切换动画)。

这例子也告诉我们前台Task可以叠加起来(仅限于前台),当这个叠加Task置于后台时这个叠加的Task又会拆分成单独的Task.

当我们拿下Home键回到桌面或者打开最近任务界面的时候Task就进入到了后台。

我们来看一下:allowTaskReparenting这个属性,当我们将activity这个属性设置为true的时候会有奇妙的事情发生!!!

我们假如在自己的app里边打开了邮箱app编写邮件的activity时候(假如这个编写邮件activity的allowTaskReparenting设置为true),新创建的属于邮箱的activity就会被放置在自己app Task的栈顶,这个时候当我们从桌面打开邮箱app的时候刚刚还在我们自己app栈顶的activity就会跑到新打开邮箱app 的Task的栈顶。注意(Android 9 Android10 部分机型会失效)。这就是allowTaskReparenting的奇妙之处(注意我们再回到我们自己的activity它不会从邮箱的Task转移到我们App的Task).

设置SingleInstance的时候因为也是全局单例所以也存在前台task叠加的情况。要把含有这个activity的Task压在启动activity的Task上边。

我们来考虑一种特殊情况:

app a : activityA 启动模式standard

app b : activityB 启动模式为singleInstance

app c : activityC 启动模式为 standard

顺序打开a -> b -> c 那么用户当前界面为app c的activityC,这个时候的Task为三个Task叠加在一块!!!!。

Android默认一个app只会有一个Task显示在最近任务列表,用TaskAffinity来甄别Task的唯一性,每个activity的taskAffinity默认为Application的TaskAffinity而Application的TaskAffinity默认是包名。每个Task的TaskAffinity取自栈底activity的taskAffinity,当我们打开一个启动模式为SingleTask的activity的时候,就会检查当前Task的TaskAffinity是否与activity的TaskAffinity相同不相同,如是相同就直接入栈,不同则将activity放在跟它TaskAffinity相同的Task中或者创建新的Task并将其放在栈顶,并且将这个Task叠加在前台Task上边。

原文地址:https://www.cnblogs.com/FCY-LearningNotes/p/14799817.html