简体   繁体   中英

Activity stack behavior when activity is started from widget

I have two avtivities. Let's call them ActivityA and ActivityB . ActivityA is marked singleTask in manifest file. I can start ActivityB from ActivityA using simple startActivity call (no Intent flags used). Also I can start ActivityC from ActivityA and start ActivityB from it (also using "simple" Intents ).

ActivityB has a button which performs this code:

Intent intent = new Intent(ActivityB.this,
                ActivityA.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

I also have a widget which can start ActivityA using this code:

Intent aIntent = new Intent(context, ActivityA.class);
aIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
                aIntent, 0);

And also it can start ActivityB from grid items:

Intent bIntent = new Intent(context, ActivityB.class);
PendingIntent bPendingIntent = TaskStackBuilder.create(context)
        .addNextIntent(aIntent).addNextIntent(bIntent )
        .getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);

If I start ActivityA from launcher, start ActivityB from it (or ActivityA -> ActivityC -> ActivityB ) - I can move back to ActyvityA (or ActivityC ) using back button or button in ActivityB (described above) and ActivityA is not recreated. That's OK.

The problem is that if I start ActivityB from widget and use back button or button in ActivityB (described above) ActivityA is recreated and becomes single instance in stack.

I want to be able to manage those two activities the way ActivityA is always the root one and NOT RECREATED if it is already running.

You can't really do this using TaskStackBuilder . You can avoid using TaskStackBuilder if you can figure out a way to making sure that ActivityB is never launched into a task unless ActivityA is already there. In this way, when ActivityB returns to ActivityA , the instance of ActivityA will not get recreated.

To solve this problem, instead of launching ActivityB directly from the widget, you should launch ActivityA and pass an extra that tells ActivityA that you want it to launch ActivityB :

Intent bIntent = new Intent(context, ActivityA.class);
bIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | 
        Intent.FLAG_ACTIVITY_NEW_TASK);
bIntent.putExtra("launchActivityB", true);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
            bIntent, 0);

In both onCreate() and onNewIntent() of ActivityA , check for the presence of the extra and if it is there you should launch ActivityB immediately.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM