5

フォアグラウンド ディスパッチ動作に厄介な問題があります。を呼び出す代わりにonNewIntent()、アクティビティを完全に再作成することがあり、アプリのワークフローが中断されます。

私の具体的な状況: アクティビティ A は、フォアグラウンド ディスパッチを使用する MainActivity です。すべてが正常に機能します。ただし、ブラウザーから起動されるアクティビティ B (VIEW アクション) では、状況によってはフォアグラウンド ディスパッチが機能しなくなりました。

ワークフロー:

  • MainActivity を開始し、(MainActivity を閉じずに) ブラウザーに切り替え、アクティビティ B を起動し、NFC デバイスを接続します --> 新しいアクティビティ B が作成されます。

  • MainActivity を開始し、もう一度閉じます。その後
    、ブラウザに切り替え、アクティビティ B を起動し、NFC デバイスを接続します --> すべてが動作しますonNewIntent()

コードは正しいです。たとえば、最初のシナリオで NFC デバイスを 2 回接続すると、2 回目は正常に動作しますが、最初は動作しません。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);
    }
}

これらのメソッドは、各アクティビティの対応するメソッドで呼び出されます。助けてくれてありがとう!

解決策:非常に長い調査の結果、最終的に問題を発見しました。ログキャットは次のように出力しました:

  • 非アクティビティ コンテキストから呼び出された startActivity。Forcing Intent.FLAG_ACTIVITY_NEW_TASK for: Intent

人々が NotificationManager で同じ問題を抱えていた Stackoverflow で他の問題を見つけましたが、すべてのヒントは役に立ちませんでした。アクティビティ B にフラグ singleTask を追加するとうまくいきましたが、正直なところ、コンテキストは常にアクティビティであるため、理解できません。

MainActivity からすべてのコードを削除しましたが、最初のシナリオはまだ機能しませんでした。マニフェストから MainActivity を奪った後、すべて問題ありませんでした。アプリ インスタンスが実行されていて、アクティビティ B がブラウザーから起動されていることが問題なのでしょうか? 知らない。

とにかく、助けてくれてありがとうNFCガイ!

4

2 に答える 2

2

IntentFilter[]渡すはenableForegroundDispatch空です。したがって、マニフェスト ファイル内の IntentFilter(s) により、NFC インテントがアクティビティに到達する可能性があります。これは、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 がどのタスクで新しいアクティビティを起動するかを決定する方法が原因です。それがどのように機能するかの具体的な詳細はわかりませんが、その効果は次のとおりです。

  1. アクティビティ B がブラウザから起動されると、ブラウザのタスクで作成されます
  2. NFC インテントが到着すると、システムは新しいアクティビティ B がアクティビティ A のタスクで作成されることを決定します。

2. のため、SINGLE_TOP は無視されません。アクティビティ B のインスタンスは、A のタスクの先頭に 1 つしかありません。アクティビティ A が閉じられると、そのタスクは消えてしまうため、ご覧のとおり、アクティビティ B は常にブラウザのタスクに作成されます。

この場合、これは Android のバグだと感じるかもしれませんが (私はそう思います)、タスクでアクティビティを作成する方法のこの動作は、多くのアプリがそれに依存する Android にとって非常に基本的なものです。したがって、これが変わる可能性はほとんどありません。

考えられる回避策: アクティビティ B をlaunchMode「singleTask」(または「singleInstance」) で宣言します。次に、B が起動されると、新しい (3 つ目の) タスクが作成されます。

于 2012-04-23T11:53:01.697 に答える
0

あなたのワークフローは次のようになっていると思います: Main --> Detect tag --> Reader Activity --> Writer activity Detect tag --> Write tag

この問題は、以前のタグ検出から呼び出されたアクティビティ スタック (タスクなど) にライター アクティビティ (フォアグラウンドが有効になっているもの、書き込み目的だと思われます) が属している場合に発生するようです。

特に、ワ​​ークフローが次のようになっている場合は発生しません: Main Writer アクティビティ タグを検出 --> タグを書き込む

私の回避策は、最初に新しいタスクでライター アクティビティを呼び出すことです。ライターを起動するアクティビティでは、ライターを起動するインテントに新しいタスク フラグを追加するだけです。

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

メイン --> タグ検出 --> リーダー アクティビティ -NEW_TASK -> ライター アクティビティ タグ検出 --> タグ書き込み

アクティビティの履歴を混乱させますが、ライターのアクティビティをより予測可能にします。

于 2014-05-04T07:49:18.170 に答える