Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/211.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 单顶|透明顶似乎在95%的时间都有效。为什么是5%?_Android_Android Activity_Android Intent_Launchmode - Fatal编程技术网

Android 单顶|透明顶似乎在95%的时间都有效。为什么是5%?

Android 单顶|透明顶似乎在95%的时间都有效。为什么是5%?,android,android-activity,android-intent,launchmode,Android,Android Activity,Android Intent,Launchmode,我有一个接近完成的应用程序,它有一个非平凡的活动结构。存在与此应用程序关联的推送通知,无论应用程序是否处于前台/后台/非活动状态,选择通知条目都会引发特定活动 如果应用程序未激活,则我已成功启动应用程序并自动导航到相应的部分。但是,当应用程序处于活动状态时,我遇到了一个问题。我将给出问题的简化版本,以说明问题的性质,并根据需要发布我的应用程序的活动结构和相关代码的详细信息(实际上,现在正在进行这方面的工作) 因此,我的应用程序的活动堆栈(大大简化)如下所示: A->B->X 其中,根活动A是登录

我有一个接近完成的应用程序,它有一个非平凡的活动结构。存在与此应用程序关联的推送通知,无论应用程序是否处于前台/后台/非活动状态,选择通知条目都会引发特定活动

如果应用程序未激活,则我已成功启动应用程序并自动导航到相应的部分。但是,当应用程序处于活动状态时,我遇到了一个问题。我将给出问题的简化版本,以说明问题的性质,并根据需要发布我的应用程序的活动结构和相关代码的详细信息(实际上,现在正在进行这方面的工作)

因此,我的应用程序的活动堆栈(大大简化)如下所示:

A->B->X

其中,根活动A是登录页面;B是一个“主页”,X是可以从主页启动的几个活动之一(但一次只有一个活动实例;因为这些活动只能从B启动)

选择通知后,我需要应用程序自动导航到B,而不管它之前处于何种状态—无论是[A]、[A->B]、[A->B->X]还是[](应用程序未激活)

我的通知将意图传递给活动A。我已尝试使用CLEAR_TOP和NEW_TASK标志,但没有。A当前具有launchmode=singleTask。这样做,我想我正在解决所有可能的现有堆栈配置,并将它们减少到[A]。意图还带有一个额外的标识,标识它来自于通知,而不是通常的启动

活动A在识别从通知发送的意图后(它可以在onCreate()和onNewIntent()中执行此操作),将意图发送到活动B。此意图包含CLEAR_TOP和SINGLE_TOP。B具有启动模式=单顶

95%的情况下,这会根据需要工作,按下通知后,应用程序的堆栈为[A->B]。 大约有5%的时间,该应用程序以某种方式以一堆[a->B->B]结束

你知道这里发生了什么事,或者我做错了什么吗

如果这不是一个小问题,我会发布更多细节。事实上,现在发布更多细节

~~~~~~~~~~~~~~~~~~~~~~~~~~~~更多详细信息~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

单步执行调试器显示,每次A向B发送其意图时,B的现有实例都是onDestroy()'d,然后才是onCreate()'d,然后还调用了其onNewIntent()。这对我来说似乎很奇怪,并表明要么我误解了我正在使用的标志(CLEAR_TOP和SINGLE_TOP),要么是其他东西干扰了它们

我没有在调试中成功地复制错误的堆栈结构。不确定这是因为调试时没有发生,还是因为我没有尝试足够的次数

意图代码:

在C2DM接收器服务中:

protected void onMessage(Context context, Intent intent) {
    int icon = R.drawable.some_drawable;
    CharSequence tickerText = "blah";
    long when = System.currentTimeMillis();
    Notification notification = new Notification(icon, tickerText, when);

    //Context context = getApplicationContext(); //Don't need this; using the context passed by the message.
    CharSequence contentTitle = intent.getStringExtra("payload");
    CharSequence contentText = "Lorem ipsum dolor si amet,";
    Intent notificationIntent = new Intent(this, LoginPage.class);
    //notificationIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); //Tried with and without
    notificationIntent.putExtra(PushManager.PUSH_INTENT, PushManager.PUSH_INTENT); //Indicator that this was send from notification

    PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
    notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);

    notificationManager.notify(PushManager.ALARM_NOTIFICATION_ID, notification);
}
在登录页面(活动A)中,成功登录后:

Intent i = new Intent(LoginPage.this, TabHomePage.class);
// (If we're automatically going to tab 2, inform next activity)
if(fromNotification) {
    i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
    i.putExtra(TabHomePage.TAB_NUMBER, TabHomePage.TAB_2);
}
startActivity(i);
有关活动堆栈结构的更多详细信息,请参见下图:

下面是千言万语:

活动A是一个登录页面;成功登录后,它将启动B。 B是一个TabActivity,其中包含三个活动(由C、D、E表示)。 C、D和E实际上都是一个ActivityGroup,其子活动模仿活动的通常堆栈行为

因此,每个选项卡都包含自己的活动堆栈,在选项卡之间切换会更改用户导航当前正在推送到/弹出的堆栈(每个选项卡都包含一个通过实体层次结构浏览的ListActivities堆栈)。除了巨大的“B”选项卡活动(由X表示)之外,它们还可以启动新的活动

因此,从活动A登录后,在接受更多用户输入之前,至少会创建三个活动: -B被创建(并且可以看到,因为TabWidget现在位于屏幕顶部) -将创建其中一个ActivityGroup:属于默认选项卡的活动组。此ActivityGroup在屏幕上仍然不显示,但是…它只显示其子活动堆栈的顶部活动。 -最后,创建ActivityGroup堆栈的“根”活动(图中,F是此类活动的一个示例)。此活动显示在TabWidget下面

每个选项卡访问一次后,不会再通过在选项卡之间切换来创建/销毁活动(不计算内存消耗)。 在任何tab finish()中按back键将在堆栈顶部显示活动,并显示其下方的活动。 在任何选项卡中,从根活动(如F)按back键完成整个TabActivity,将用户发送回A


传递给B的意图还指示它自动导航到与默认选项卡不同的选项卡。在我们以[a->B->B]堆栈结束的情况下,第一个B被导航到正确的选项卡,第二个是默认的;博士不要同时使用透明顶部和单顶部

如果只在5%的时间内产生错误,则可能是并发问题。您说过您有用于调用活动B的SINGLE_TOP | CLEAR_TOP。CLEAR_TOP将销毁活动B的当前实例,并将意图传递给onCreate()。SINGLE_TOP不会销毁活动B的当前实例,并将意图传递给onNewIntent()

首先读取SINGLE_TOP标志时,意图将传递到调用onNewIntent()的活动B的当前实例。然后读取CLEAR_TOP,销毁活动B,并使用onCreate()创建一个新实例,一切正常

首先读取CLEAR_TOP时,将销毁活动B的现有实例,并使用onCreate()创建一个新实例。然后读取SINGLE_TOP,并将意图传递给onNewIntent()。再说一次,它成功了

当同时读取CLEAR_TOP和SINGLE_TOP时,活动i的当前实例