28

Like:

startActivity(intent);
finish();

Without calling finish() explicitly, onDestroy() is not called for the former Activity, and I run out of memory (OutOfMemory Exception).

So, is it a good idea to call finish() explicitly to prevent OutOfMemory Exception?

Tarsem Singh
  • 14,139
  • 7
  • 51
  • 71
Marton_hun
  • 584
  • 2
  • 7
  • 18
  • what if user wants to return to previous activity by clicking back button? – Raghunandan Aug 07 '13 at 18:42
  • 2
    No. Your problem is somewhere else. – fdreger Aug 07 '13 at 18:42
  • Are you using `Bitmap` (or a collection of) anywhere? If you haven't yet used [mat Memory Analyzer Tool](http://www.eclipse.org/mat/), now is a good time. – haventchecked Aug 07 '13 at 18:44
  • When you call finish() , you are removing the activity from backstack basically , so if you move to another activity and decides to come back for example through on backpress , it will crash because the activity no longer exists in the backstack so that it gets called , the only way to go back to an activity even after removing it from the backstack by creating an intent so simple creating a new instance of that activity – Taki Aug 25 '21 at 03:55

3 Answers3

41

When you start a new activity, the current activity is pushed onto the back stack of the current task. (You can change this behavior via flags and/or the manifest, but this is the default behavior.) When the user presses the back function, the top activity is finished and the stack is popped. The result is that the user sees the app return to the previous activity.

It's perfectly fine to call finish() after starting a new activity. The result will be that the current activity (which is no longer at the top of the stack, since you just started a new one) will be removed from the stack. Then when the user presses Back, it will go to the previous activity on the back stack (or exit your app if the stack is empty).

If you are bouncing back and forth between, say, activities A and B by always starting a new one and never calling finish(), this can cause an OOM exception as the stack fills up with instances of each activity.

You can read more about this in the guide topic Tasks and Back Stack. It also describes how to deal correctly with cycling between activities.

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
  • Great answer. Thank you. – stevehs17 Apr 06 '16 at 04:15
  • Does the order of `startActivity(intent); finish();` these two statements matter at all? – Weishi Z Sep 02 '16 at 07:54
  • 1
    @WeishiZeng - I've done it both ways and it seems to make no difference. I don't think it matters. – Ted Hopp Sep 02 '16 at 14:46
  • @TedHopp Thanks! I've also seen both working. But just curious that, is it possible that `finish()` leads to destruction of current activity instance before `startActivity(intent)` happens? Then it's problematic as both `intent` and `startActivity()` won't exist without its associated instance. – Weishi Z Sep 02 '16 at 20:39
  • @WeishiZeng - I don't think there's a problem. The activity might be destroyed (although that may happen on a subsequent pass of the UI loop) but the activity object instance still exists. – Ted Hopp Sep 02 '16 at 21:52
  • @TedHopp By "destroyed", do you mean that 1) onDestroy() called, and 2) removed from task stack? But the activity instance is not eligible for gc? – Weishi Z Sep 02 '16 at 23:32
  • @WeishiZeng - Yes, I meant both. I'm not sure if `onDestroy()` is called immediately, but it should make no difference. The activity instance is not eligible for gc because the system has a reference to the intent, which has a reference to the activity. So as far as the gc is concerned, the instance is still alive. – Ted Hopp Sep 04 '16 at 00:58
2

Doing this is fine if you don't need an instance of that Activity. So when you press back on the next Activity know that you won't come back to this one but whatever is on the stack below where that Activity was or the home screen if there are no more.

However, I'm not sure this is why you are getting an OOM exception and you should probably figure out where that is coming from instead. If you are using Bitmaps then that could be causing the exception.

codeMagic
  • 44,549
  • 13
  • 77
  • 93
  • Yes, I use Bitmaps. Without calling explicitly finish(), GC doesn't call onDestroy() of the Activity, and the Activity's loaded Bitmap resources takes up much memory, therefore I end up outOfMemoryException. If onDestroy() is not called by GC does it mean a memory leak? If there is no reference to the Activity, shouldn't the GC call ondestroy() when more memory is needed? – Marton_hun Aug 07 '13 at 19:37
1

Alternatively in the manifest you could add android:noHistory="true" to the activity and when you navigate away from the activity it will not add it to the back stack.

Jordan Hochstetler
  • 1,308
  • 3
  • 17
  • 28