launchMode="singleTask"不会创建新任务

8

我有两个活动:Activity A 和 Activity B。Activity A 的启动模式是标准模式,而 Activity B 的启动模式是 singleTask 模式。

 <activity
    android:name=".AActivity"
    android:label="@string/app_name"
    android:launchMode="standard">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>

    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <data android:scheme="dd"></data>
        <data android:host="a"></data>
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
    </intent-filter>
</activity>
<activity
    android:name=".BActivity"
    android:label="@string/app_name"
    android:launchMode="singleTask">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <data android:scheme="dd"></data>
        <data android:host="b"></data>
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
    </intent-filter>
</activity>

我打开应用程序,启动了启动器Activity A。然后我按下Home按钮并返回到手机的主屏幕。接着,我打开浏览器应用,并输入以下内容:

dd://b

打开B活动。系统导航到我的应用程序并在A活动之上启动B活动。此时,如果我按返回按钮,B活动就会被弹出,我就能看到A活动。

这不是我所期望的,因为Android文档说明:

对于singleTask活动,系统会创建一个新任务并在新任务的根部实例化活动。但是,如果该活动的实例已经存在于另一个任务中,则系统通过调用其onNewIntent()方法将意图路由到现有实例,而不是创建新的实例。每次只能存在一个活动实例。

从这些句子中我理解到,在我的情况下,由于不存在B活动的实例,应该启动一个新任务,并且它的堆栈中应该只有B活动(我的应用程序的另一个实例仍然存在于单独的任务中,并且应该具有A活动在它的堆栈中)。然后,如果我在B活动中按返回键,由于它是后退堆栈中唯一的活动,它就会被弹出,系统就会返回浏览器。

为什么情况不是这样?Android系统如何知道我的应用程序已经打开并导航到它并在现有应用程序堆栈的顶部启动B活动,而不是启动我的应用程序的另一个实例并让这两个应用程序实例拥有自己的堆栈?在新任务中实例化活动是什么意思?有人能解释一下吗?

谢谢。

2个回答

8
除了已接受的答案外,我找到了这个问题的解释。正如Android文档所述:
亲和力表示活动希望属于哪个任务。默认情况下,同一应用程序中的所有活动都具有彼此的亲和力。因此,默认情况下,同一应用程序中的所有活动都喜欢在属于该应用程序(包含Activity B的应用程序)的同一任务中。但是,您可以修改活动的默认亲和性。
因此,如果您的应用程序正在运行,并且您启动一个具有“launchMode:singleTask”属性的活动,除非您明确指定“taskAffinity”属性,否则它会在同一任务中启动该活动。但是,如果您在清单中明确指定了亲和力:
<activity
        android:name=".BActivity"
        android:label="@string/app_name"
        android:taskAffinity=""
        android:launchMode="singleTask">
</activity>

然后它会在新任务中开始该活动。

您可以通过以下adb命令查看哪个活动属于哪个任务:

adb shell dumpsys activity

另外,为了更好地理解启动模式的概念,您可以在Google Play上查看以下应用程序:https://play.google.com/store/apps/details?id=com.novoda.demos.activitylaunchmode


这进一步解释了它。不错的发现。 - Rahul Tiwari
Android文档中指出,“singleTask:系统会创建新任务并在新任务的根位置实例化活动。”接着补充说:“无论活动是在新任务中启动还是与启动它的活动在同一任务中启动,返回按钮始终将用户带回到先前的活动。那么你如何确定“singleTask”不会默认启动一个新任务呢?” https://developer.android.com/guide/components/activities/tasks-and-back-stack.html - frankelot

0

你说你的应用程序通过A导航到B。

所以,我认为你有两个堆栈。在第一个堆栈中,你只有A,在第二个堆栈中,你只有B。如果你按返回键,那么B将被弹出并消失,但A仍然存在并显示,因为A在B后面,即使A和B在不同的堆栈中。

如果你想让B弹出,然后返回主页,请在从A调用B之后调用“finish()”。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接