8

我有2个活动:活动A和活动B。活动A的启动模式是标准的,活动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 启动。然后我按主页按钮并返回手机的主屏幕。然后我启动浏览器应用程序并输入以下内容:

dd://b

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

这不是我所期望的,因为 android 文档指出:

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

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

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

谢谢。

4

2 回答 2

8

除了接受的答案之外,我还找到了对这个问题的解释。正如android文档所述:

亲和性指示活动更喜欢属于哪个任务。默认情况下,来自同一个应用程序的所有活动都彼此具有亲和性。因此,默认情况下,同一个应用程序中的所有活动都倾向于属于属于该应用程序的同一任务(具有活动 B 的应用程序)。但是,您可以修改活动的默认亲和性。

因此,如果您的应用程序正在运行,并且您启动了一个具有launchMode:singleTask属性的活动,除非您明确声明taskAffinity属性,否则它将在同一任务中启动该活动。但是,如果您在清单中明确声明亲和性:

<activity
        android:name=".BActivity"
        android:label="@string/app_name"
        android:taskAffinity=""
        android:launchMode="singleTask">
</activity>

然后它在新任务中启动活动。

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

adb shell dumpsys activity

此外,为了更好地理解 launchMode 概念,您可以在 Google Play 中查看以下应用:https: //play.google.com/store/apps/details? id=com.novoda.demos.activitylaunchmode

于 2015-09-28T19:43:26.467 回答
0

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

所以,我认为你有两个堆栈。在第一个中,您只有 A,在第二个中,您只有 B。如果您按回,则 B 弹出并消失,但 A 存在并显示,因为 A 在 B 后面,即使 A 和 B 在单独的堆栈中。

如果你想让 B 弹出然后你回到家,在从 A 调用 B 之后尝试调用“finish()”

于 2015-09-28T13:29:38.470 回答