launchMode="singleTask" 不创建新任务
launchMode="singleTask" does not create a new task
我有 2 个活动: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 启动。然后我按主页按钮和 return 到 phone 的主屏幕。然后我启动浏览器应用程序并键入以下内容:
dd://b
打开 Activity B. 系统导航到我的应用程序并在 activity 之上启动 activity B A. 此时如果我按下后退按钮,activity B 弹出,我看到 activity A.
这不是我所期望的,因为 android 文档指出:
For singleTask activities, the system creates a new task and instantiates the activity at the root of the new task. However, if an instance of the activity already exists in a separate task, the system routes the intent to the existing instance through a call to its onNewIntent() method, rather than creating a new instance. Only one instance of the activity can exist at a time.
我从这些句子中理解的是,在我的例子中,由于 Activity B 的实例不存在,一个新任务应该已经启动并且它应该只有 Activity B 在它的堆栈(我的应用程序的另一个实例应该仍然存在于一个单独的任务中,并且它的堆栈中应该有 Activity A)。然后,如果我在 Activity B 时按回键,因为它是后台堆栈中唯一的 activity,它会弹出,系统 returns 到浏览器。
为什么不是这样? android 系统如何知道我的应用程序已打开并导航到它并在现有应用程序堆栈顶部启动 activity B 而不是启动我的应用程序的另一个实例并让我的应用程序的两个实例拥有自己的实例堆栈? 在新任务中实例化 activity 是什么意思? 谁能解释一下?
谢谢。
您说您的应用在经过 A 时导航到 B。
所以,我认为你有两个堆栈。在第一个中,你只有 A,在第二个中你只有 B。如果你向后按,那么 B 会弹出并消失,但 A 存在并且正在显示,因为即使 A 和 B 在单独的堆栈中,A 在 B 后面。
如果你想要那个 B pop 然后你 return 回家,试着在从 A
呼叫 B 之后再呼叫 "finish()"
除了接受的答案外,我还找到了对这个问题的解释。正如 android 文档所述:
The affinity indicates which task an activity prefers to belong to. By default, all the activities from the same application have an affinity for each other. So, by default, all activities in the same application prefer to be in the same task which belongs to that app(The app that has the Activity B). However, you can modify the default affinity for an activity.
因此,如果您的应用是 运行,并且您启动了具有 launchMode:singleTask
属性的 activity,除非您明确声明 taskAffinity 属性,它在同一任务中启动 activity。但是,如果您在清单中明确声明亲和力:
<activity
android:name=".BActivity"
android:label="@string/app_name"
android:taskAffinity=""
android:launchMode="singleTask">
</activity>
然后它在新任务中启动 activity。
可以通过下面的adb命令查看哪个activity属于哪个任务:
adb shell dumpsys activity
此外,为了更好地理解 launchMode 概念,您可以在 Google Play 中查看以下应用:https://play.google.com/store/apps/details?id=com.novoda.demos.activitylaunchmode
我有 2 个活动: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 启动。然后我按主页按钮和 return 到 phone 的主屏幕。然后我启动浏览器应用程序并键入以下内容:
dd://b
打开 Activity B. 系统导航到我的应用程序并在 activity 之上启动 activity B A. 此时如果我按下后退按钮,activity B 弹出,我看到 activity A.
这不是我所期望的,因为 android 文档指出:
For singleTask activities, the system creates a new task and instantiates the activity at the root of the new task. However, if an instance of the activity already exists in a separate task, the system routes the intent to the existing instance through a call to its onNewIntent() method, rather than creating a new instance. Only one instance of the activity can exist at a time.
我从这些句子中理解的是,在我的例子中,由于 Activity B 的实例不存在,一个新任务应该已经启动并且它应该只有 Activity B 在它的堆栈(我的应用程序的另一个实例应该仍然存在于一个单独的任务中,并且它的堆栈中应该有 Activity A)。然后,如果我在 Activity B 时按回键,因为它是后台堆栈中唯一的 activity,它会弹出,系统 returns 到浏览器。
为什么不是这样? android 系统如何知道我的应用程序已打开并导航到它并在现有应用程序堆栈顶部启动 activity B 而不是启动我的应用程序的另一个实例并让我的应用程序的两个实例拥有自己的实例堆栈? 在新任务中实例化 activity 是什么意思? 谁能解释一下?
谢谢。
您说您的应用在经过 A 时导航到 B。
所以,我认为你有两个堆栈。在第一个中,你只有 A,在第二个中你只有 B。如果你向后按,那么 B 会弹出并消失,但 A 存在并且正在显示,因为即使 A 和 B 在单独的堆栈中,A 在 B 后面。
如果你想要那个 B pop 然后你 return 回家,试着在从 A
呼叫 B 之后再呼叫 "finish()"除了接受的答案外,我还找到了对这个问题的解释。正如 android 文档所述:
The affinity indicates which task an activity prefers to belong to. By default, all the activities from the same application have an affinity for each other. So, by default, all activities in the same application prefer to be in the same task which belongs to that app(The app that has the Activity B). However, you can modify the default affinity for an activity.
因此,如果您的应用是 运行,并且您启动了具有 launchMode:singleTask
属性的 activity,除非您明确声明 taskAffinity 属性,它在同一任务中启动 activity。但是,如果您在清单中明确声明亲和力:
<activity
android:name=".BActivity"
android:label="@string/app_name"
android:taskAffinity=""
android:launchMode="singleTask">
</activity>
然后它在新任务中启动 activity。
可以通过下面的adb命令查看哪个activity属于哪个任务:
adb shell dumpsys activity
此外,为了更好地理解 launchMode 概念,您可以在 Google Play 中查看以下应用:https://play.google.com/store/apps/details?id=com.novoda.demos.activitylaunchmode