分析一个过度使用启动模式造成的问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/willway_wang/article/details/83959414

1 前言

Android 定义了四种启动模式:standard、singleTop、singleTask 和 singleInstance。默认情况下,是 standard 模式。这种模式在绝大多数情况下是没有问题的。因此,在大多数情况下,都不需要去设置启动模式。过度使用启动模式也会给自己的程序带来一些问题,有时候也是很难测试出来的问题。下面就介绍一个过度使用启动模式造成的 bug。

2 正文

2.1 场景介绍

操作步骤如下:

1,通过一个 SplashActivity,打开 MainActivity 页面(启动模式是 singleInstance),把 SplashActivity finish 掉;
2,再通过 MainActivity 打开 SecondActivity 页面(启动模式是 standard);
3,按下 Home 键;
4,点击应用图标,进入应用;
5,再按返回键。

按照我们的想法,应该是显示 MainActivity 页面,但其实是回到了桌面。根本就没有回到 MainActivity 页面。可以看一下,录制的 gif:

那么,这是什么原因呢?又该如何解决这一问题呢?

2.2 分析问题

下边使用一边操作,一边查看任务栈的方式具体看一下。
查看任务栈的命令是:

adb shell dumpsys activity activities

在打开 SecondActivity 后,查看一下任务栈如下:

Display #0 (activities from top to bottom):
  Stack #1:
    Running activities (most recent first):
      TaskRecord{396214d #990 A=com.wzc.chapter_1 U=0 sz=1}
        Run #2: ActivityRecord{63fdfc6 u0 com.wzc.chapter_1/.SecondActivity t990}
      TaskRecord{2bb1a1 #989 A=com.wzc.chapter_1 U=0 sz=1}
        Run #1: ActivityRecord{87511bb u0 com.wzc.chapter_1/.MainActivity t989}
      TaskRecord{d9cba29 #886 A=com.android.incallui U=0 sz=1}
        Run #0: ActivityRecord{426adbc u0 com.android.incallui/.InCallActivity t886}

    mResumedActivity: ActivityRecord{63fdfc6 u0 com.wzc.chapter_1/.SecondActivity t990}
    mLastPausedActivity: ActivityRecord{87511bb u0 com.wzc.chapter_1/.MainActivity t989}

  Stack #0:
    Running activities (most recent first):
      TaskRecord{4f9b995 #866 A=com.huawei.android.launcher U=0 sz=1}
        Run #0: ActivityRecord{34da953 u0 com.huawei.android.launcher/.Launcher t866}

    mLastPausedActivity: ActivityRecord{34da953 u0 com.huawei.android.launcher/.Launcher t866}

从上面可以看出,MainActivity 和 SecondActivity 是在不同的任务栈中,这是因为 MainActivity 设置的启动模式是 singleInstance。

按下 Home 键后,查看一下任务栈如下:

Display #0 (activities from top to bottom):
  Stack #0:
    Running activities (most recent first):
      TaskRecord{4f9b995 #866 A=com.huawei.android.launcher U=0 sz=1}
        Run #0: ActivityRecord{34da953 u0 com.huawei.android.launcher/.Launcher t866}

    mResumedActivity: ActivityRecord{34da953 u0 com.huawei.android.launcher/.Launcher t866}

  Stack #1:
    Running activities (most recent first):
      TaskRecord{396214d #990 A=com.wzc.chapter_1 U=0 sz=1}
        Run #2: ActivityRecord{63fdfc6 u0 com.wzc.chapter_1/.SecondActivity t990}
      TaskRecord{2bb1a1 #989 A=com.wzc.chapter_1 U=0 sz=1}
        Run #1: ActivityRecord{87511bb u0 com.wzc.chapter_1/.MainActivity t989}
      TaskRecord{d9cba29 #886 A=com.android.incallui U=0 sz=1}
        Run #0: ActivityRecord{426adbc u0 com.android.incallui/.InCallActivity t886}
        
    mLastPausedActivity: ActivityRecord{63fdfc6 u0 com.wzc.chapter_1/.SecondActivity t990}

这时,我们的应用退到了后台,桌面进入了前台。是这样的。

点击应用图标,进入应用:

Display #0 (activities from top to bottom):
  Stack #1:
    Running activities (most recent first):
      TaskRecord{396214d #990 A=com.wzc.chapter_1 U=0 sz=1}
        Run #2: ActivityRecord{63fdfc6 u0 com.wzc.chapter_1/.SecondActivity t990}
      TaskRecord{2bb1a1 #989 A=com.wzc.chapter_1 U=0 sz=1}
        Run #1: ActivityRecord{87511bb u0 com.wzc.chapter_1/.MainActivity t989}
      TaskRecord{d9cba29 #886 A=com.android.incallui U=0 sz=1}
        Run #0: ActivityRecord{426adbc u0 com.android.incallui/.InCallActivity t886}

    mResumedActivity: ActivityRecord{63fdfc6 u0 com.wzc.chapter_1/.SecondActivity t990}

  Stack #0:
    Running activities (most recent first):
      TaskRecord{4f9b995 #866 A=com.huawei.android.launcher U=0 sz=1}
        Run #0: ActivityRecord{34da953 u0 com.huawei.android.launcher/.Launcher t866}

    mLastPausedActivity: ActivityRecord{34da953 u0 com.huawei.android.launcher/.Launcher t866}

再按 back 键,我们回到了桌面,查看任务栈:

Display #0 (activities from top to bottom):
  Stack #0:
    Running activities (most recent first):
      TaskRecord{4f9b995 #866 A=com.huawei.android.launcher U=0 sz=1}
        Run #0: ActivityRecord{34da953 u0 com.huawei.android.launcher/.Launcher t866}

    mResumedActivity: ActivityRecord{34da953 u0 com.huawei.android.launcher/.Launcher t866}
    mLastPausedActivity: ActivityRecord{34da953 u0 com.huawei.android.launcher/.Launcher t866}

  Stack #1:
    Running activities (most recent first):
      TaskRecord{2bb1a1 #989 A=com.wzc.chapter_1 U=0 sz=1}
        Run #1: ActivityRecord{87511bb u0 com.wzc.chapter_1/.MainActivity t989}
      TaskRecord{d9cba29 #886 A=com.android.incallui U=0 sz=1}
        Run #0: ActivityRecord{426adbc u0 com.android.incallui/.InCallActivity t886}

    mLastPausedActivity: ActivityRecord{63fdfc6 u0 com.wzc.chapter_1/.SecondActivity t990 f}

可以看到的是, MainActivity 确实还存在的,但是却没有显示在前台。
这时,再去点击一个应用图标,查看任务栈:

Display #0 (activities from top to bottom):
  Stack #1:
    Running activities (most recent first):
       TaskRecord{2bb1a1 #989 A=com.wzc.chapter_1 U=0 sz=1}
        Run #1: ActivityRecord{87511bb u0 com.wzc.chapter_1/.MainActivity t989}
      TaskRecord{d9cba29 #886 A=com.android.incallui U=0 sz=1}
        Run #0: ActivityRecord{426adbc u0 com.android.incallui/.InCallActivity t886}

    mResumedActivity: ActivityRecord{f71f6f8 u0 com.wzc.chapter_1/.MainActivity t994}
    mLastPausedActivity: ActivityRecord{9bb5ec8 u0 com.wzc.chapter_1/.SplashActivity t996 f}

  Stack #0:
    Running activities (most recent first):
      TaskRecord{4f9b995 #866 A=com.huawei.android.launcher U=0 sz=1}
        Run #0: ActivityRecord{34da953 u0 com.huawei.android.launcher/.Launcher t866}

    mLastPausedActivity: ActivityRecord{34da953 u0 com.huawei.android.launcher/.Launcher t866}

可以看到,显示出来的是原来存在的 MainActivity。
但这是怎么回事呢?
其实,这是由于过度使用启动模式造成的。把 MainActivity 的启动模式设置成 singleTask 就可以了。

最后

本文并没有分析出具体的原因,只是找到了对应的解决办法。欢迎大家留言,一起讨论这个问题。代码地址:https://github.com/jhwsx/android-art-research/tree/master/chapter_1

参考

Android启动模式之singleinstance的坑

猜你喜欢

转载自blog.csdn.net/willway_wang/article/details/83959414