Android单实例活动,如果按下返回按钮,则不再是单个实例。

8

我遇到了一个有趣的问题,即使在清单文件中将Activity定义为singleTask或singleInstance,它仍然会被创建多次。以下是如何重现此问题。假设在主Activity中:

@Override
protected void onResume() {
    Intent i = new Intent(MainActivity.class, SingleActivity.class);
    startActivity(i);
}

在我的SingleActivity中,我有:

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    Log.i("SingleActivity", "onCreate " + System.identityHashCode(this));
    ...
}

在清单文件中,我有以下内容:
    <activity android:name=".SingleActivity"
              android:launchMode="singleInstance"
    />

现在,如果我启动应用程序,一切似乎都很正常,只有一个问题:如果我在SingleActivity在前台时按下“返回”按钮,它会导航回到MainActivity,其中MainActivity.onResume()将创建另一个SingleActivity实例,而不是将已经存在的实例带到前面。这是我知道的,因为日志显示了不同的标识哈希码。

如果启动模式为singleTask,则情况相同。

唯一的解决方法似乎是重写onBackPressed(),但这似乎是一个丑陋的解决方案。

我想知道我做错了什么。


那么你应该投票支持解决了你问题的答案,这就是Stackoverflow的工作方式! - Waza_Be
哦,我看到你在追求Karma分数 :) 给你。 - Ákos Maróy
2个回答

14

这是一个关于taskAffinity的问题。因为你在manifest文件中的MainActivitySingleActivity都没有指定taskAffinity,所以这两个活动都有相同(默认)的taskAffinity。当启动一个活动时,Android会检查你想要启动的活动的taskAffinity。如果它与你任务中根活动的taskAffinity相同,那么它将会忽略launchMode="singleInstance"launchMode="singleTask"(因为这些启动模式需要在新任务中启动该活动),并在当前任务中启动该活动。

不幸的是,这个问题没有得到很好的记录,但是taskAffinitylaunchMode更具优先级。

如果你真的需要一个singleTasksingleInstance活动(通常不是正确的做法,因为它会带来一系列其他难以处理的问题),那么你需要确保你的singleInstancesingleTask活动在manifest文件中的<activity>定义中有以下内容:

android:taskAffinity=""
如果您需要更多信息,请在StackOverflow或Google上搜索“launchmode taskaffinity”。

1
如果所有活动都已完成,任务将被销毁,因此当重新启动活动时,即使活动已指定“singleInstance”标志,它也将重新创建活动。 - Autobots
“它带来了一堆其他容易出错的麻烦”是什么意思?在我的情况下,我正在使用launchMode="singleInstance"和android:taskAffinity=""作为我的启动器应用程序,一切正常。 - Pascal
1
@Pascal 如果你的应用程序中有多个活动,这会变得复杂。而且,如果你的应用程序可以被另一个应用程序启动,那么它就会变得更加复杂。通常情况下,使用singleTasksingleInstance会引起比解决更微妙的行为问题。很少需要使用特殊的启动模式。根据我的经验,大多数人尝试使用它来解决他们并不真正理解的问题。 - David Wasser
好的。在我的情况下,我只是在我的启动器中这样做,这对我来说没有问题。谢谢。 - Pascal

5

默认情况下,按下后退键会结束(销毁)当前活动并向用户显示上一个活动。

因此,不可能

而不是呈现已经存在的内容

因为没有任何活动存在。


1
你确定这个活动被销毁了吗?虽然我没有查看代码,但每次我在手机上按返回键后,我都可以稍后恢复该活动(它从未被销毁)。 - c0dehunter
这正在发生在我身上。 - Ninja Coding

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