Skip to content

Android: OutOfMemory error and the backstack

the following sheet represents the working flow in the application this question is about.

workflow

I ran into problems with OutOfMemory Errors, mostly because users were able to switch from activity B to activity D multiple times (They are showing different content for every attempt), without the previous activity being destroyed. This led into a very large backstack resulting in an OutOfMemory error.

To avoid this, I followed the recommendation to add parent activites to the manifest and create new backstacks with the TaskStackBuilder class:

void openDFromB()
{
    Intent i = new Intent(this, ActivityD.class);
    TaskStackBuilder.create(this)
        .addParentStack(ActivityD.class)
        .addNextIntent(i)
        .startActivities();
}

If a user now switches from activity B to D, MainMenu, A and B are destroyed and a new Backstack (MainMenu, C, D) is created. This solves my memory problems for api level greater 10, but unfortunately the TaskStackBuilder does not create backstacks for devices pre api 11.

Any idea what to do in order to avoid users stacking infinite amounts of activities prior api 11? Is this even possible or should I try to free as many resources as possible in onPause to gain a maximum amount of stacked activities before OoM?

thanks in advance!

Answer

Zabri answer is good, but i would propose another probably is better: You dont close every activity, but when you are opening a new activity that has been open before, you tell the system that it can clear the way back and reopen that one, of course with a new intent and all the new data that you need.

So, if you do A – B – D – B – D – B, instead of having that big stack,you will have

  1. A – B
  2. A – B – D
  3. A – B
  4. A – B – D
  5. A – B

So, if you do C – D – B – D – B – D, your stack will be

  1. C – D
  2. C – D – B
  3. C – D
  4. C – D – B
  5. C – D

and so on. In this way, i think the stack actually reflects what the user can have in mind, and also navigation is very logic, you don’t even need to captre back button to have the navigation making sense, (of course you can do it if you want a more specific user experience)

The code to achieve this, is: create a function that receives a class (something like ActivityD.class), there you create an intent, with the flags Intent.FLAG_ACTIVITY_CLEAR_TOP and Intent.FLAG_ACTIVITY_NEW_TASK and then when you need to open an activity, just call this function. You dont care about if the activity is in the stack or not. If it isnt,it is created normally.

 protected void startActivity(Class<?> clase) {
    final Intent i = new Intent(this, clase);
    int flags = Intent.FLAG_ACTIVITY_CLEAR_TOP;
    flags |= Intent.FLAG_ACTIVITY_NEW_TASK;
    i.setFlags(flags);
    startActivity(i);
}


startActivity(ActivityD.class);