Android Activity的Launch mode详解

bug记录:APP 在手机点击主菜单是退出应用后再返回APP,APP未停留在之前离开的页面。

demo演示

bug排查: 查看Activity的生命周期
Android Activity的Launch mode详解_第1张图片
在重新进入app的过程中,activity活动栈中所有被singleTask Activity 之上的所有activity 被Destory

Bug原因

当A activity启动模式为SingleTask并且为Main,启动应用后会创建一个taskAffinity 的活动栈,然后点击进入其他Activity。当按home键后,这个栈后到后台,所有的Activity为stop状态。当再次点击Launcher图片进入到app应用:

实质是重新startActivity并传递一个新的Intent给Main activity,SingleTask Activity 会从 onNewIntent进入并delete ALL 其top 活动

系统将会寻找是否有taskAffinity栈,恰好这个后台的活动栈被启动到前台。由于SingleTask模式的特点,它将清除所有它之上stop的活动,所以来BUG了。

另外提:在任务管理界面进入,是不会产生这个现象

Demo地址


乘此良机,是时候记录一波Android Activity的LaunchMode。

Launch Mode

官方文档

  • “standard”(默认模式)
    默认。系统在启动 Activity 的任务中创建 Activity 的新实例并向其传送 Intent。Activity 可以多次实例化,而每个实例均可属于不同的任务,并且一个任务可以拥有多个实例。
  • “singleTop”
    如果当前任务的顶部已存在 Activity 的一个实例,则系统会通过调用该实例的 onNewIntent() 方法向其传送 Intent,而不是创建 Activity 的新实例。Activity 可以多次实例化,而每个实例均可属于不同的任务,并且一个任务可以拥有多个实例(但前提是位于返回栈顶部的 Activity 并不是 Activity 的现有实例)。
    例如,假设任务的返回栈包含根 Activity A 以及 Activity B、C 和位于顶部的 D(堆栈是 A-B-C-D;D 位于顶部)。收到针对 D 类 Activity 的 Intent。如果 D 具有默认的 “standard” 启动模式,则会启动该类的新实例,且堆栈会变成 A-B-C-D-D。但是,如果 D 的启动模式是 “singleTop”,则 D 的现有实例会通过 onNewIntent() 接收 Intent,因为它位于堆栈的顶部;而堆栈仍为 A-B-C-D。但是,如果收到针对 B 类 Activity 的 Intent,则会向堆栈添加 B 的新实例,即便其启动模式为 “singleTop” 也是如此。

注:为某个 Activity 创建新实例时,用户可以按“返回”按钮返回到前一个 Activity。 但是,当 Activity 的现有实例处理新 Intent 时,则在新 Intent 到达 onNewIntent() 之前,用户无法按“返回”按钮返回到 Activity 的状态。

  • “singleTask”
    系统创建新任务并实例化位于新任务底部的 Activity。但是,如果该 Activity 的一个实例已存在于一个单独的任务中,则系统会通过调用现有实例的 onNewIntent() 方法向其传送 Intent,而不是创建新实例。一次只能存在 Activity 的一个实例。
    注:尽管 Activity 在新任务中启动,但是用户按“返回”按钮仍会返回到前一个 Activity。

  • “singleInstance”.
    与 “singleTask” 相同,只是系统不会将任何其他 Activity 启动到包含实例的任务中。该 Activity 始终是其任务唯一仅有的成员;由此 Activity 启动的任何 Activity 均在单独的任务中打开。

你可能感兴趣的:(Android)