1

In my app there are three activities.

A can open B

B can open C, or return to A, or return to C (if opened from C)

C can open B, or return to A

I have implemented this using various RESULT_CODEs and onActivityResults. However, the stack becomes too large after prolonged use of the app!

I need to clear activities from the stack. Looking at my app's structure, the best clearing method revolves around clearing whatever is the second activity on the stack (assuming A is always the first/bottom activity on the stack). I made a quick painting to make it easier to understand:

enter image description here

Once B is added onto ABC, the previous B (second activity in the stack) is removed. Once C is added onto ACB, the previous C (second activity in the stack) is removed.

I can think of two methods that do what I describe:

  1. clear whatever is the second activity in the stack

  2. remove any activities in the stack that are the same as the one that I am creating (C creates B, so the other B needs to be cleared)

However, I have not found a way to implement this in code. I have tried using Intent.FLAG_ACTIVITY_CLEAR_TOP, but that clears everything in the stack except for A, before adding the new activity at the top.

So my question: How can I implement method 1 or method 2? (Does not matter which one)

Here is an example of me clearing all in the stack but A:

Intent newActivity = new Intent(this, B.class);
newActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivityForResult(newActivity, MY_REQUEST_CODE);

I am also open to alternative methods. Maybe using FLAG_ACTIVITY_NO_HISTORY somehow?

Chronicle
  • 1,565
  • 3
  • 22
  • 28
  • 2
    Not sure what your activities are doing but this sounds like a perfect use case for fragments. See my answer here, https://stackoverflow.com/questions/34667170/manage-the-backstack-in-android/34667350#34667350, for an example of reusing existing fragments in the stack and limiting the backstack depth. – Cory Charlton Jan 19 '16 at 18:39

5 Answers5

2

So it seems like you would like to keep one instance of B activity and C activity. This can be done with adding an XML attribute in your Manifest.xml

<activity android:name="B" android:launchMode="singleTask" </activity>

"singleTask" - The system creates the activity at the root of a new task and routes the intent to it. However, if an instance of the activity already exists, the system routes the intent to existing instance through a call to its onNewIntent() method, rather than creating a new one. Refer to here for more information.

Nelson Hoang
  • 413
  • 2
  • 11
  • This seemed perfect at first, but I've noticed that after adding that attribute to the manifest, that upon returning to the `A` activity, `onActivityResult` is not called – Chronicle Jan 19 '16 at 22:28
1

I have occurred the same problem , to kill some specific activity .. my solution was to implement StackActivityManager used for managing activity :

  1. Each activity was saved on static list which contains all activity of my application
  2. The saving of activity was done the mother class base activity

  3. Each activity have a static and unique tag used later to indicate which activity will be remove from the stack of activity

  4. The launch mode is singleTask to avoid duplicate activity in the stack of activity.
Sofien Rahmouni
  • 4,354
  • 1
  • 21
  • 22
1

try to do method:

Intent intent = new Intent(Activity1.this, Activity2.class);
startActivity(intent);

//The finish(); method, destroy the current activity. 
finish();

after call the next activity, then the current activity destroys. I hope that it works. :)

Joan Sanchez
  • 331
  • 3
  • 8
  • This would work great if the activities were starting another version of themselves (like `B` starting another `B`). Unfortunately in my case `B` always starts a `C` , and it is the previous `C` that would then need to be cleared, not the `B`. – Chronicle Jan 19 '16 at 22:30
0

remove this line

newActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

Try adding in your code-

Intent newActivity = new Intent(this, B.class);
newActivity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
newActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivityForResult(newActivity, MY_REQUEST_CODE);
Nihal Singh
  • 144
  • 4
0

Note: What Cory Charlton wrote in his comment about Fragments is probably the best solution for anyone having similar problems. I recommend trying that route instead of my own solution. The only reason I went with my own solution is because I needed a quick solution, and had not the time to learn how to implement Fragments before a deadline.

I ended up solving the problem by having the A activity always start the C activity, instead of the B activity. The B activity no longer creates a C activity, it instead finishes in order to go back to C.

This way the stack never gets bigger than 3.

And to provide some code, I had to add this before finishing in the B activity, since it now no longer is passing an object, but is returning it:

setResult(RESULT_OK, getIntent().putExtra(KEY_MY_OBJECT, myObject));
Chronicle
  • 1,565
  • 3
  • 22
  • 28