Java 安卓;单顶“;发射方式和方法

Java 安卓;单顶“;发射方式和方法,java,android,android-activity,android-intent,android-manifest,Java,Android,Android Activity,Android Intent,Android Manifest,我在Android文档中读到,通过将我的Activity的launchMode属性设置为singleTop或将标志\u Activity\u SINGLE\u TOP标志添加到我的Intent,调用startActivity(Intent)将重用单个Activity实例,并在onNewIntent回调中给出我的意图。这两件事我都做过,而且每次都会触发onNewIntent从不触发和onCreate触发。文档中还说,this.getIntent()返回首次创建活动时第一次传递给该活动的意图。在on

我在Android文档中读到,通过将我的Activity的launchMode属性设置为singleTop或将
标志\u Activity\u SINGLE\u TOP
标志添加到我的Intent,调用
startActivity(Intent)
将重用单个Activity实例,并在
onNewIntent
回调中给出我的意图。这两件事我都做过,而且每次都会触发
onNewIntent
从不触发和
onCreate
触发。文档中还说,
this.getIntent()
返回首次创建活动时第一次传递给该活动的意图。在
onCreate
中,我正在调用
getIntent
,每次我都会得到一个新的对象(我在另一个活动中创建intent对象并向其中添加一个额外的对象…如果它每次都返回相同的intent对象,那么这个额外的对象应该是相同的)。所有这些让我相信,我的活动并不像一个“单顶”,我不明白为什么

为了增加一些背景信息,以防我只是缺少了一个必需的步骤,下面是清单中的活动声明和我用来启动活动的代码。在这方面,活动本身没有做任何值得一提的事情:

在AndroidManifest.xml中:

    <activity
        android:name=".ArtistActivity"
        android:label="Artist"
        android:launchMode="singleTop">
    </activity>     

您是否检查是否也调用了
onDestroy()
?这可能就是为什么每次都会调用
onCreate()
,而不是
onNewIntent()
,只有当活动已经存在时才会调用它

例如,如果您通过“后退”按钮退出活动,则默认情况下会将其销毁。但是,如果您在活动堆栈上更高的位置进入其他活动,并从那里再次调用您的
ArtistActivity.class
,它将跳过
onCreate()
,直接转到
onNewIntent()
,因为活动已经创建,并且您将其定义为
singleTop
Android不会创建它的新实例,而是使用已经存在的实例

我所做的是为了了解发生了什么,我为每个活动的所有不同状态实现了虚拟函数,所以我现在总是知道发生了什么:

@Override
public void onDestroy() {
    Log.i(TAG, "onDestroy()");
    super.onDestroy();
}
同样适用于
onRestart()
onStart()
onResume()
onPause()
onDestroy()


如果上面的(后退按钮)不是您的问题,那么实现这些假人至少可以帮助您更好地调试它。

公认的答案并不完全正确。如果以前调用过onDestroy(),则始终会调用yes,onCreate()。然而,这种说法是错误的: “如果您在“活动”堆栈中的位置更高,进入其他活动,然后再次调用Artistativity.class,它将跳过onCreate(),直接转到onNewIntent()。”

的“singleTop”部分清楚地解释了它的工作原理(请注意下面的粗体文本;我也通过自己的调试证明了这一点):

“例如,假设任务的后堆栈由根活动a组成,活动B、C和D位于顶部(堆栈为a-B-C-D;D位于顶部)。类型为D的活动的意图到达。如果D具有默认的“标准”“启动模式,类的一个新实例启动,堆栈变为a-B-C-D-D。但是,如果D的启动模式为“singleTop”,则D的现有实例通过onNewIntent()接收意图,因为它位于堆栈的顶部,堆栈仍为a-B-C-D。但是,如果类型B的活动到达意图,然后,一个新的B实例被添加到堆栈中,即使它的启动模式是“singleTop”。

换句话说,通过SINGLE_TOP启动一个活动只会重用已经位于堆栈顶部的现有活动。如果同一任务中的另一个活动位于堆栈顶部(例如,正在执行startActivity(SINGLE_TOP))它将不起作用;将创建一个新实例

这里有两种方法来解决这个问题,这样你就可以得到你想要的单一行为——其一般目的是重用现有的活动,而不是创建一个新的活动

第一种方式(如接受的 答):您可以将“singleTask”的启动模式添加到您的活动中。这将强制onNewIntent(),因为singleTask意味着给定任务中只能有一个特定活动的实例。但这是一个有点骇人听闻的解决方案,因为如果您的应用程序在特定情况下需要该活动的多个实例(就像我为我的项目所做的那样),你完蛋了

第二种方式(更好): 使用FLAG\u ACTIVITY\u REORDER\u TO\u FRONT来代替FLAG\u ACTIVITY\u SINGLE\u TOP。这将通过将现有活动实例移动到堆栈顶部来重用它(将按预期调用onNewIntent()


FLAG_ACTIVITY_SINGLE_TOP的主要目的是防止创建一个活动的多个实例。例如,当该活动可以通过来自应用程序主任务之外的意图启动时。对于我的应用程序中活动之间的内部切换,我发现FLAG_ACTIVITY_REORDER_to_FRONT通常是w我想要的是什么。

根据您的意图设置此标志:

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP)

很可能就是这样,我创建了一个类似“登录页”的东西"活动作为入口点。从登录点,您选择一个艺术家,然后转到ArtistActivity。用户使用“后退”按钮返回到主要活动,然后再次选择。我的印象是,该活动在首次使用后会挂起,我可以通过不重新实例化来节省性能。我应该担心吗这里的性能,或者这种模式适合简单的活动吗?嗨,我和OP有同样的问题,但在我的情况下,onDestroy从未被调用-我只是以全新的活动实例结束:-s。还有其他想法吗?android:launchMode=“singleTask”-在我的情况下,是q中的活动
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP)