Avoiding Android Memory Leaks: Part 1
I recently discovered how easy it is to accidentally “leak” memory and resources in an Android application.
In this tutorial, I’ll illustrate a memory leak with a simple dialog box example, and then show you how to fix it.
Let’s start by creating a simple Android application that displays a dialog in its onCreate event:
package com.justinschultz.android; import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.os.Bundle; public class LeakedDialogActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setIcon(android.R.drawable.ic_dialog_alert); builder.setMessage("This dialog leaks!").setTitle("Leaky Dialog").setCancelable(false).setPositiveButton("Ok", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) {} }); AlertDialog alert = builder.create(); alert.show(); } }
If you’ve copied this correctly, the app should look like this:
While this application is running, take a look in LogCat. (In Eclipse, LogCat can be displayed via Window -> Show View -> LogCat.)
While the dialog is displayed, rotate the device (or the emulator by pressing CTRL+F11).
You should see a lot of bright red error text in LogCat that looks something like this:
Even though it looks like everything is working correctly on the device, LogCat displays this error message:
Activity com.justinschultz.android.LeakedDialogActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@40543ec0 that was originally added here
So… what happened?
When the device rotates, the onPause and onStop Activity events are invoked. Then a new landscape Activity is created, and its onCreate method is invoked.
Since the dialog is displayed and has a reference to the Activity, it can’t be garbage collected, and subsequently is leaked. That is, you’ve created an object that can’t be garbage collected.
To fix this, let’s make the dialog an Activity member variable and override the onPause method to dismiss it:
AlertDialog _alert; @Override public void onPause() { super.onPause(); if(_alert != null) _alert.dismiss(); }
This will dismiss the dialog each time the Activity is destroyed and recreated and the error will magically disappear from LogCat.
Here’s the source for this example.
About this entry
You’re currently reading “ Avoiding Android Memory Leaks: Part 1 ,” an entry on Public Static Droid Main
- Published:
- 1.10.12 / 10pm
- Category:
- Uncategorized
2 Comments
Jump to comment form | comments rss [?] | trackback uri [?]