4

launchMode が singleTop であるアクティビティがあります (マニフェスト内)。私の理解では、Activity が singleTop で、Activity スタックの一番上にある場合、新しい Intent で Activity を起動すると、Activity の新しいインスタンスが作成されることなく、実際に Activity で onNewIntent() が呼び出されます。 (したがって、onCreate() は呼び出されません)。

このアクティビティは、進行中の通知を表示するフォアグラウンド サービスを実行します。選択すると、この通知により、スタックの一番上にあるアクティビティにユーザーが戻されます (この singleTop アクティビティから起動されるアクティビティはありません)。私の問題は、通知が選択されると、Activity の新しいインスタンスが作成されることがあるということです。アクティビティがバックグラウンドで強制終了され、再起動された場合 (vs. onNewIntent() で前面に出された場合) とは動作が異なるように意図されているため、これは私のアクティビティにとって問題です。私のサービスが通知を表示するために使用するコードは次のとおりです。

TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(MainActivity.class);

Intent notificationIntent = new Intent(this, MyProblematicActivity.class);
notificationIntent.putExtra(EXTRA_MY_DATA, "MyData");
stackBuilder.addNextIntent(notificationIntent);

PendingIntent pendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);

Notification.Builder notificationBuilder = new Notification.Builder(getApplicationContext()).
        setSmallIcon(smallIconResourceId).
        setContentTitle(contentTitle).
        setContentText(contentText).
        setAutoCancel(false).
        setOngoing(true).
        setContentIntent(pendingIntent);

startForeground(MY_NOTIF_ID, notificationBuilder.build());

このような動作が時々発生すると言いますが、発生すると、繰り返し発生します。例えば:

  1. MyProblematicActivity が初めて起動されました
  2. サービスが開始され、通知が表示されます
  3. 通知が選択されています。
  4. MyProblematicActivity が再度作成されます (サービスは既に開始されており、通知は既に表示されています)。
  5. 2 ~ 4 回の forevs を繰り返します。

時折、#3 の後、MyProblematicActivity の onNewIntent() が新しいインスタンスを作成せずに呼び出され、期待どおりに動作しました。

なぜこれが起こっているのか、私にはわかりません。タスクのルートにあるステート アクティビティは、singleTop アクティビティの動作に影響を与えますか? FWIW、MyProblematicActivity を作成するアクティビティは singleTask アクティビティです。

4

3 に答える 3

0

コマルが言ったことと同じことで答えていますが、この全体の背後にある理由を説明するためだけに、

を使用する場合singleTop、新しいインスタンスは、ターゲット アクティビティがスタックの一番上にある場合にのみ呼び出されません。スタックの一番上にない場合は、新しいインテントがonNewIntent(). したがって、新しいインスタンスが作成されます。

そう、

フラグを追加Intent.FLAG_ACTIVITY_CLEAR_TOP

現在のスタック上のアクティビティまで移動すると、その動作は親アクティビティの起動モードによって決定されます。親アクティビティの起動モードが singleTop の場合 (または up インテントに FLAG_ACTIVITY_CLEAR_TOP が含まれている場合)、親はスタックの一番上に移動し、その状態は保持されます。ナビゲーション インテントは、親アクティビティの onNewIntent() メソッドによって受け取られます。親アクティビティの起動モードが標準の場合 (およびアップ インテントに FLAG_ACTIVITY_CLEAR_TOP が含まれていない場合)、現在のアクティビティとその親の両方がスタックからポップされ、ナビゲーション インテントを受け取るために親アクティビティの新しいインスタンスが作成されます。

ドキュメンテーション

于 2014-12-23T07:45:29.317 に答える