ywwynm
ywwynm

Reputation: 11695

Start new Activity from BroadcastReceiver will resume existed Activity

I had Activity A(launchMode is singleTask) and B. In onCreate() of A, I triggered an alarm, which will activate a BroadcastReceiver after some time. Then I pressed home button to hide A.

In that BroadcastReceiver's onReceive(), following code will be executed:

Intent intent = new Intent(context, B.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);

And then I found B was launched normally, but A will also be resumed. I don't know why and don't like that behavior.

Let's imagine: user opened you app's Activity A, pressed home button and opened another app's Activity B, then a BroadcastReceiver is activated and Activity C of your app is opened, user did some stuff there and then he pressed back button. He should see B instead of A, right?

How can I forbid this behavior? Thanks in advance.

Upvotes: 0

Views: 1034

Answers (3)

ywwynm
ywwynm

Reputation: 11695

I found an appropriate solution by myself, again...

Add android:taskAffinity="hello.world"(Any string different from your app's package name and contains at least one point is good) for Activity A in AndroidManifest.xml.

Reason? When start an Activity with FLAG_ACTIVITY_NEW_TASK, it will check if there was a task existed with same taskAffinity. If yes, it won't create new task but will be pushed to that task directly. In our case, since we don't have android:taskAffinity="..." written, all Activities have same taskAffinity. As a result, when B is launched from BroadcastReceiver, it is added to default app task where A is existed in, too. I think, then the default app task will be activated and all Activities inside it are going to be pushed into top of back stack. Then we know the result: pressing back button in B will lead us to A.

Other behavior change? Yes. If using this method, B cannot have multiple instances unless launch it with one more flag: FLAG_ACTIVITY_MULTIPLE_TASK.

Interesting related discovery? Yes. I find that if pressing home button in A and launching B in BroadcastReceiver soon in 5 seconds, then B will display after a delay. But if B is launched after more seconds, it will display very quickly. This is a protection by Android system, for more details, you can reference Delay while launching activity from service. Trust me, this is very very inconspicuous but interesting(And no solution:).

Upvotes: 2

Nakul
Nakul

Reputation: 1329

I think you will need to add one more flag Intent.FLAG_ACTIVITY_NO_HISTORY.

Intent intent = new Intent(context, B.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY);
context.startActivity(intent);

App's current behavior can be explained in this answer. As suggested in linked answer,

If your app is already running, Android will just launch the Activity into that task.

So extra flag Intent.FLAG_ACTIVITY_NO_HISTORY will help.


Edit

Based on discussion in comment, You can check if Your activity is in background or foreground (this can help) and depending upon result use Intent flag Intent.FLAG_ACTIVITY_CLEAR_TASK.

Upvotes: 0

codingma
codingma

Reputation: 1

Just add a line of setting in AndroidManifest.xml for B Activity.

android:launchMode="singleInstance"

Use the simplest way to start the B activity

context.startActivity(new Intent(context,B.class));

But this way has a problem,it will influence all places when B activity is started.

Upvotes: 0

Related Questions