Sunday, 23 September 2012

leaked window that was originally added here


Snippet of my AddRideActivity.java is

private boolean YES = false;

AlertDialog.Builder builder = new AlertDialog.Builder(
AddRideActivity.this);
builder.setTitle("Add Suspension Settings")
.setMessage(Configuration.ADD_SUSPENSION_SETTINGS)
.setCancelable(true)
.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
@Override
public void onClick(
DialogInterface dialog, int arg1) {
YES = false;
dialog.dismiss();
}
})
.setNegativeButton("Later",
new DialogInterface.OnClickListener() {

@Override
public void onClick(
DialogInterface dialog,
int which) {
// startActivity to
// HomeActivity.class
dialog.dismiss();

}
});
AlertDialog myAlertDialog = builder.create();
myAlertDialog.show();


if (!YES) {
Toast.makeText(getApplicationContext(),
"Ride Successfully Added", Toast.LENGTH_SHORT)
.show();
AddRideActivity.this.setResult(RESULT_OK);
AddRideActivity.this.finish();
} else {
// FIXME AddRideActivity return Ride after added to db
}


But I'm getting following error :


09-23 23:08:43.086: E/WindowManager(828): Activity com.twomonkers.mxsuspensionlite.AddRideActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@44f02830 that was originally added here
09-23 23:08:43.086: E/WindowManager(828): android.view.WindowLeaked: Activity com.twomonkers.mxsuspensionlite.AddRideActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@44f02830 that was originally added here
09-23 23:08:43.086: E/WindowManager(828): at android.view.ViewRoot.<init>(ViewRoot.java:247)
09-23 23:08:43.086: E/WindowManager(828): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
09-23 23:08:43.086: E/WindowManager(828): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
09-23 23:08:43.086: E/WindowManager(828): at android.view.Window$LocalWindowManager.addView(Window.java:424)
09-23 23:08:43.086: E/WindowManager(828): at android.app.Dialog.show(Dialog.java:241)
09-23 23:08:43.086: E/WindowManager(828): at com.twomonkers.mxsuspensionlite.AddRideActivity$6.onClick(AddRideActivity.java:291)
09-23 23:08:43.086: E/WindowManager(828): at android.view.View.performClick(View.java:2408)
09-23 23:08:43.086: E/WindowManager(828): at android.view.View$PerformClick.run(View.java:8816)
09-23 23:08:43.086: E/WindowManager(828): at android.os.Handler.handleCallback(Handler.java:587)
09-23 23:08:43.086: E/WindowManager(828): at android.os.Handler.dispatchMessage(Handler.java:92)
09-23 23:08:43.086: E/WindowManager(828): at android.os.Looper.loop(Looper.java:123)
09-23 23:08:43.086: E/WindowManager(828): at android.app.ActivityThread.main(ActivityThread.java:4627)
09-23 23:08:43.086: E/WindowManager(828): at java.lang.reflect.Method.invokeNative(Native Method)
09-23 23:08:43.086: E/WindowManager(828): at java.lang.reflect.Method.invoke(Method.java:521)
09-23 23:08:43.086: E/WindowManager(828): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
09-23 23:08:43.086: E/WindowManager(828): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
09-23 23:08:43.086: E/WindowManager(828): at dalvik.system.NativeStart.main(Native Method)


Solution
I changed the above code as following :

AlertDialog.Builder builder = new AlertDialog.Builder(
AddRideActivity.this);
builder.setTitle("Add Suspension Settings")
.setMessage(Configuration.ADD_SUSPENSION_SETTINGS)
.setCancelable(true)
.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
@Override
public void onClick(
DialogInterface dialog, int arg1) {

dialog.dismiss();

Toast.makeText(
getApplicationContext(),
"Ride Successfully Added",
Toast.LENGTH_SHORT).show();
Intent intent = new Intent(
AddRideActivity.this,
AddSuspensionActivity.class);
intent.putExtra("RIDE_ID", rideId);
startActivity(intent);

}
})
.setNegativeButton("Later",
new DialogInterface.OnClickListener() {

@Override
public void onClick(
DialogInterface dialog,
int which) {
// startActivity to
// HomeActivity.class
dialog.dismiss();
Toast.makeText(
getApplicationContext(),
"Ride Successfully Added",
Toast.LENGTH_SHORT).show();
AddRideActivity.this
.setResult(RESULT_OK);
AddRideActivity.this.finish();
}
});
AlertDialog myAlertDialog = builder.create();
myAlertDialog.show();

References
1 - http://stackoverflow.com/questions/2850573/activity-has-leaked-window-that-was-originally-added

The solution is to call dismiss() on the Dialog you created in AddRideActivity.java before exiting the Activity, e.g. in onPause().
Views have a reference to their parent Context (taken from constructor argument). If you leave an Activity without destroying Dialogs and other dynamically created Views, they still hold this reference to your Activity (if you created with this as Context: like new ProgressDialog(this)), so it cannot be collected by the GC, causing a memory leak.

No comments:

Post a Comment