5

我对前台调度行为有一个烦人的问题。有时它不会调用onNewIntent(),而是完全重新创建活动,这会破坏应用程序的工作流程。

我的具体情况:Activity A 是 MainActivity,它使用前台调度。一切正常。但是,在从浏览器(VIEW 操作)启动的活动 B 中,前台调度在某些情况下不再起作用。

工作流程:

  • 我启动 MainActivity,切换到浏览器(不关闭 MainActivity),启动 Activity B 并附加我的 NFC 设备 --> 它创建了一个新的 Activity B。

  • 我启动 MainActivity 并再次关闭它。之后我切换
    到浏览器,启动活动 B 并附加我的 NFC 设备 --> 一切正常onNewIntent()

代码是正确的,例如,如果我在第一个场景中两次连接 NFC 设备,它会在第二次正常工作,但不是在第一次。在 MainActivity 和活动 BI 中,明确调用活动的 onPause() 方法中的 disableForegroundDispatch() 方法。

我的具体问题有解决方案吗?对我来说,这听起来像是一个错误。

编辑:

public void resume(Activity targetActivity) {
    if (nfc != null && nfc.isEnabled()) {
        // nfc is the default NFC adapter and never null on my devices

        Intent intent = new Intent(targetActivity, targetActivity.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(targetActivity, 0, intent, 0);
        nfc.enableForegroundDispatch(targetActivity, pendingIntent, null, new String[][] { new String[] { IsoDep.class.getName() } });
    }
}

public void pause(Activity targetActivity) {
    if (nfc != null && nfc.isEnabled()) {
        nfc.disableForegroundDispatch(targetActivity);
    }
}

这些方法在每个活动的相应方法中被调用。谢谢您的帮助!

解决方案:经过很长时间的研究,我终于找到了问题所在。Logcat 打印:

  • 从非活动上下文调用的 startActivity;强制 Intent.FLAG_ACTIVITY_NEW_TASK 用于:意图

我在 Stackoverflow 发现了其他问题,人们对 NotificationManager 也有同样的问题,但所有的提示都没有帮助我。将标志 singleTask 添加到我的活动 B 对我来说是诀窍,但老实说我不明白,因为上下文始终是一个活动。

我从 MainActivity 中删除了所有代码,第一个场景仍然不起作用。我从清单中删除了 MainActivity,之后一切都很好。也许这是一个问题,应用程序实例正在运行并且活动 B 从浏览器启动?我不知道。

无论如何,感谢NFC家伙的帮助!

4

2 回答 2

2

IntentFilter[]你传递给的那个enableForegroundDispatch是空的。因此,由于清单文件中的 IntentFilter(s),您的 NFC 意图可能会到达您的 Activity。这解释了您观察到的行为,因为 NFC 意图总是在以这种方式交付时创建一个新实例。

将类似这样的内容添加到您的代码中以启用前台调度:

IntentFilter[] iFilters = new IntentFilter[2];
iFilters[0] = new IntentFilter();
iFilters[0].addAction("android.nfc.action.TECH_DISCOVERED");
iFilters[1] = new IntentFilter();
iFilters[1].addAction("android.nfc.action.TAG_DISCOVERED");
iFilters[1].addCategory(Intent.CATEGORY_DEFAULT);

并将其作为参数传递给enableForegroundDispatch.

更新:我最近了解了更多关于这个特定问题的信息。它是由 Android 确定应该在哪个任务中启动新 Activity 的方式引起的。我不知道或不了解它是如何工作的具体细节,但效果是:

  1. 当Activity B从浏览器启动时,它是在浏览器的任务中创建的
  2. 当 NFC Intent 到达时,系统确定要在 Activity A 的任务中创建一个新的 Activity B

由于 2.,SINGLE_TOP 没有被忽略:在 A 的任务顶部只有一个 Activity B 实例。当 Activity A 关闭时,它的任务已经消失,所以 Activity B 将始终在 Browser 的任务中创建,正如您所观察到的。

在这种情况下,您可能会觉得这是一个 Android 错误(我认为是这样),但是这种如何创建任务的行为对于 Android 来说是如此基础,以至于许多应用程序都依赖它。因此,这种情况不太可能改变。

可能的解决方法:使用launchMode“singleTask”(或“singleInstance”)声明活动 B。然后,当 B 启动时,将创建一个新的(第三个)任务。

于 2012-04-23T11:53:01.697 回答
0

我猜你的工作流程如下: Main --> Detect tag --> Reader Activity --> Writer activity Detect tag --> Write tag

当您的编写器活动(启用了前台的活动,我想这是出于编写目的)属于从先前的标签发现中调用的活动堆栈(例如任务)时,似乎会出现此问题。

特别是,如果您的工作流程如下所示,则不会出现: Main Writer activity Detect tag --> Write tag

我的解决方法是首先在新任务中调用编写器活动。在启动编写器的活动中,只需在启动编写器的意图中添加新任务标志。

startActivity(new Intent(this,MyTagWriterActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));

Main --> Detect tag --> Reader Activity -NEW_TASK-> Writer 活动 Detect tag --> Write tag

它确实与活动历史记录混淆,但使作者活动更可预测。

于 2014-05-04T07:49:18.170 回答