当使用 startActivityForResult 启动活动时,LaunchMode "singleTop" 会被忽略
Posted
技术标签:
【中文标题】当使用 startActivityForResult 启动活动时,LaunchMode "singleTop" 会被忽略【英文标题】:LaunchMode "singleTop" is ignored when activity is started with startActivityForResult 【发布时间】:2020-02-01 22:44:01 【问题描述】:我使用startActivityForResult()
启动一个活动,并希望防止在活动堆栈顶部启动多个实例。所以我希望android:launchMode="singleTop"
能够完成它的工作,但由于某种原因,该标志被忽略了。
经过一些调查,我设法通过在意图中添加FLAG_ACTIVITY_REORDER_TO_FRONT
来仅启动一个实例,但如果有人能解释为什么“singleTop”在这种情况下不起作用,我将不胜感激。代码很简单。
// Activity class
Intent intent = new Intent(this, DetailsActivity.class);
// multiple instances can be launched without this line
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivityForResult(intent, REQUEST_CODE_DETAILS);
// AndroidManifest.xml
<activity
android:name=".DetailsActivity"
android:launchMode="singleTop"/>
【问题讨论】:
【参考方案1】:SingleTop 是如何工作的?
假设您有当前的活动堆栈,例如
A->B->C
现在从当前活动 C,如果你启动 A 活动,它是一个单一的Top,所以在这种情况下,系统将创建一个新的 A 实例并将该实例带到顶部。 (如果指定的活动不在顶部,则将创建新实例)
所以堆栈看起来像
A->B->C->A
现在,如果您再次尝试打开 A,那么在这种情况下,A 已经在顶部,因此将创建 NO 新实例。相反,A 将在 onNewIntent() 方法中接收回调
标志
FLAG_ACTIVITY_REORDER_TO_FRONT
它从堆栈的前端扫描到堆栈的后端,如果找到指定活动的实例,则将该活动带到前面。
所以在你的情况下,如果 DetailsActivity instacne 已经存在于系统中,那么这个标志会将 DetailsActivity 带到前面
【讨论】:
是的,这就是我所期望的,这就是它在通常的 startActivity() 中的工作方式。但是如果使用 startActivityForResult() 和 launchMode="singleTop" 启动活动 C,A->B->C 堆栈会变成 A->B->C->C 并且不会调用 onNewIntent()。【参考方案2】:在这种情况下必须忽略标志FLAG_ACTIVITY_SINGLE_TOP
,因为当您使用startActivityForResult()
启动Activity
时,您基本上是在说您要启动Activity
并让Activity
返回结果。
如果此Activity
的实例已存在于堆栈中(无论它在堆栈中的什么位置),则该实例尚未设置为将结果返回给您的Activity
。该实例可能是使用startActivity()
启动的,在这种情况下,它根本没有设置为返回结果。它可能是使用另一个Activity
的startActivityForResult()
启动的,在这种情况下,它被设置为将结果返回给启动它的Activity
,而不是你的Activity
。
这两件事:FLAG_ACTIVITY_SINGLE_TOP
和 startActivityForResult()
因此是冲突的。
【讨论】:
以上是关于当使用 startActivityForResult 启动活动时,LaunchMode "singleTop" 会被忽略的主要内容,如果未能解决你的问题,请参考以下文章
为啥当我解构属性时接收道具的组件不起作用,但是当我使用 props.key 时它起作用了?