美文网首页
Android - Activity LaunchMode 简例

Android - Activity LaunchMode 简例

作者: 拾识物者 | 来源:发表于2019-03-26 22:53 被阅读0次

    本文不详细介绍基础概念,适合一知半解,想要彻底弄清楚的同学食用。

    Activity 的 LaunchMode 有四种取值:

    • standard
    • singleTop
    • singleTask
    • singleInstance

    这个取值有两方面的影响:

    1. 是否创建新的 Activity 实例
    2. 创建的 Activity 实例在哪个 task 里

    是否创建新的 Activity 实例

    如果创建新的 Activity 实例,那么一定是走 onCreate() > onStart() > onResume() 这个生命周期路线。

    如果不创建,也就是复用之前存在的,则一定会调用 onNewIntent(),其他生命周期方法视具体情况而定。

    • standard 默认模式。一定会创建新的实例。
    • singleTop 栈顶复用模式。如果要启动的实例所在的task顶部已经有了一个实例,才可以复用之前。其他情况,比如:
      • 原来并没有这个 Activity 的实例。
      • 原来有这个 Activity 的实例,但并不在栈顶。
      • 原来有这个 Activity 的实例,但是和要启动的实例不在一个 task 中。
    • singleTask 栈内复用模式。如果原来有一个实例在某个 task 内,则一定会复用,不会创建新的实例。如果原来没有,则会创建实例。
      • 复用的时候还有一个作用是清除掉原实例上面的所有 Activity
    • singleIntance 单例模式。这种 Activity 只能存在在一个 task 中,并且这个 task 只能有这一个 Activity。与 singleTask 类似,有则复用,没有则创建。

    创建的 Activity 实例在哪个 task 里

    taskAffinity 属性

    • 是一个字符串,是 task 在设备范围内的全局名称
    • 如果不设置,taskAffinity 默认值是应用的包名
    • 所有模式都可以指定这个属性,都有可能有用,见下文:

    基本规则

    • standard 谁启动它,就和谁在一个 task 内。
      • 除非是 singleInstance 启动它,它肯定不会和 singleInstance 在一个 task 内,而是使用自己的 taskAffinity 决定。
    • singleTop 与 standard 相同。
    • singleTask 始终创建在 taskAffinity 指定的 task 内,如果没有则创建这个 task。
    • singleInstance 始终独占一个 task,没有就创建这个 task。

    验证方法

    打印 taskAffinity、taskId、launchMode

    private static String[] S = {
        "standard", "singleTop", "singleTask", "singleInstance"};
    public static String getTaskDebugString(Activity activity) {
        try {
            ActivityInfo info = activity.getPackageManager()
                .getActivityInfo(
                    activity.getComponentName(), 
                    PackageManager.GET_META_DATA);
            return info.taskAffinity + "#" + activity.getTaskId()
                + "(" + S[info.launchMode] + ")";
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            return "";
        }
    }
    

    一些例子

    以下表格表示各种组合情况下,启动 Main > A > B 的过程中,获取的 task 的信息。

    以下表格内 standard(A) 表示 standard 模式,括号表示设置的 taskAffinity。

    Main A B Task(Main,A,B) 解析
    standard singleInstance standard X,Y,X singleInstance就是和别人不一样
    standard(P) singleInstance standard(P) X,Y,X 显式设置相同的 taskAffinity,其实跟不设置是一样的
    standard(P) singleInstance standard(Q) X,Y,Z 具有不同taskAffinity的standard中间插一个singleInstance,也放在了不同的task中
    standard(P) singleInstance(P) standard(P) X,Y,X 即使手动设置了singleInstance的taskAffinity,也是没有影响,不会和别的在一个task内
    singleIntance standard(P) standard(Q) X,Y,Y standard启动standard会忽略taskAffinity
    standard singleTask standard X,X,X Main和A的taskAffinity相同,singleTask也不会创建新的task
    standard(P) singleTask(P) standard(Q) X,Y,Y 同上
    standard singleTask(P) standard(Q) X,Y,Y Main和A的taskAffinity不相同了,就启动了新的task
    standard singleTask(P) standard X,Y,Y 即使B与Main的taskAffinity相同,但是standard自己决定不了task要跟启动者相同
    singleTask(P) singleTask(Q) standard(P) X,Y,Y -
    singleTask(P) singleTask(Q) standard(P,NT) X,Y,X NT表示NEW_TASK flag

    结论

    想要彻底理解 launchMode,只要记住以下几点:

    • standard 和 singleTop 不自己决定 task。
    • singleTask 和 singleInstance 自己决定 task。
    • taskAffinity 表示任务名字,不设置默认是包名。
    • NEW_TASK flag 使 Activity 有自主决定 task 的权利,taskAffinity 才有效。

    相关文章

      网友评论

          本文标题:Android - Activity LaunchMode 简例

          本文链接:https://www.haomeiwen.com/subject/tpyovqtx.html