FLAG_ACTIVITY_NEW_TASK not behaving as expected wh

2019-05-29 21:16发布

Ok, bear with me here

My App is composed of a splash screen activity (A) and the main activity (B). When the app starts, (A) is displayed for a bit and then it starts (B). Afterwards (A) is finished. This works fine under "normal" conditions. Here is the code to launch (B)

final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
    @Override
    public void run() {
        Intent mainIntent = new Intent(A.this, B.class);
        startActivity(mainIntent);
        finish();
    }
}, SPLASH_DELAY);

When a notification arrives, and the user clicks on it. I'm starting (A) by means of a PendingIntent:

Intent mIntent = new Intent(this, A.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, mIntent, PendingIntent.FLAG_CANCEL_CURRENT);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this).setSmallIcon()... //build the whole notification
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(0, mBuilder.build());

This starts (A) and then (B) and its all good.

However...

Once the app is showing on the screen and a second notification arrives (A) does not start again nor do I get any callback in (B)

Reading the documentation at http://developer.android.com/guide/components/tasks-and-back-stack.html#ActivityState I concluded that I should start (A) with the FLAG_ACTIVITY_NEW_TASK set (so that it starts a new task only if (A) isn't already running) and I should also start (B) with the flag FLAG_ACTIVITY_SINGLE_TOP (so I can get a callback to B.onNewIntent(), because B will be running). So I did

...
mainIntent.setFlags(FLAG_ACTIVITY_NEW_TASK);
....

mIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
....

but alas, no. The behaviour doesn't seem to change at all.

Am I missing something from the docs? It seems to me that FLAG_ACTIVITY_NEW_TASK should start (A) every time in my case, because by the time the second notification arrives. (A) has already finished but it just doesn't do anything.

Can you give me some lights on how to get any callback so I can display the correct info to the user?

Thanks

1条回答
神经病院院长
2楼-- · 2019-05-29 21:39

For the notification, you have created a PendingIntent for the root activity (the "start" activity) of your task and you've set FLAG_ACTIVITY_NEW_TASK. This will do the following:

  • If your application is not running, it will create a new task and launch activity A into it

  • If your application is already running (ie: there is already an active task which was started by launching activity A, even if activity A is no longer alive), it will bring that task to the foreground in whatever state it was in. This will not create any new activities, nor will it call onNewIntent() on any existing activity. This is purely "shorthand" for "bring my task to the foreground", similar to what happens when the user selects your application from the "list of recent tasks".

If you want your application to get some information every time that the user clicks on a notification, then you need to either:

  • Use a separate activity that you launch from the notification. This activity must not be the root activity (ie: the "start" activity of your application. This activity will be launched when the user selects the notification. If your application is already running, this activity will be launched into the existing task of your application. It can then determine if the application is already running (use Activity.isTaskRoot() to determine this) and do something appropriate (like launch the root activity if the application isn't already running).

  • Use the following combination of flags when launching your root activity from the notification: FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP. This will remove any other activities from the task on top of the root activity and will call onNewIntent() on the root activity. This is your "callback". NOTE: This will only work if your root activity (splash activity) has not been finished yet! This means that when activity A starts activity B it must not call finish()

查看更多
登录 后发表回答