Good day! Mr. Spock here.
I have created an ErrorListener
for my Android MediaPlayer
. If I try to display an AlertDialog
from my handler, it causes a "leaked window" exception to occur when the "OK" button is pressed on the dialog. Here are the relevant code snippets:
Class definition:
public class PlayMediaActivity extends Activity implements OnPreparedListener, OnErrorListener, MediaController.MediaPlayerControl
Creating MediaPlayer
:
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setOnErrorListener(this);
mediaController = new MediaController(this);
try {
mediaPlayer.setDataSource(URL);
mediaPlayer.prepareAsync();
mediaPlayer.start();
}
catch(...) {} // Omit real code for brevity.
MediaPlayer
prepared listener:
public void onPrepared(MediaPlayer mediaPlayer) {
Log.d(TAG, "onPrepared");
mediaController.setMediaPlayer(this);
mediaController.setAnchorView(findViewById(R.id.main_audio_view));
handler.post(new Runnable() {
public void run() {
mediaController.setEnabled(true);
mediaController.show();
}
});
}
MediaPlayer
error listener:
public boolean onError(MediaPlayer mp, int what, int extra) {
ShowDialog("Unable to play audio. Try again later.");
return true;
}
ShowDialog
routine:
private void ShowDialog(String message) {
// Alert the user something went wrong.
ContextThemeWrapper cw = new ContextThemeWrapper( PlayMediaActivity.this, R.style.AlertDialogTheme );
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder( cw );
alertDialogBuilder.setTitle("Oops!");
// set dialog message
alertDialogBuilder
.setMessage(message)
.setCancelable(true) // Allow back hardkey to dismiss
.setPositiveButton("OK",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id) {
// if this button is clicked, close current activity
dialog.dismiss();
PlayMediaActivity.this.finish();
}
});
alertDialogBuilder.setOnCancelListener(new DialogInterface.OnCancelListener() { // Catch back key press.
@Override
public void onCancel(DialogInterface dialog) {
//do whatever you want the back key to do
dialog.dismiss();
PlayMediaActivity.this.finish();
}
});
// create alert dialog
AlertDialog alertDialog = alertDialogBuilder.create();
// show it
alertDialog.show();
}
When I call ShowDialog
from the onError
routine, it pops up, but when I press the "OK" button the activity is stopped and destroyed but the dialog is leaked (according to the stack trace), even though I'm calling dismiss()
before finishing the activity.
There are quite a few stackoverflow posts on this kind of topic, but none have solved my problem. I'm pretty new to Android development and my guess is I'm doing something fundamentally wrong but I can't put my finger on it.
Does anyone see what the problem might be?
EDIT 1 - Including StackTrace:
04-14 14:38:08.089: E/WindowManager(2099): Activity com.lcboise.lifechurch.PlayMediaActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@405619f8 that was originally added here
04-14 14:38:08.089: E/WindowManager(2099): android.view.WindowLeaked: Activity com.lcboise.lifechurch.PlayMediaActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@405619f8 that was originally added here
04-14 14:38:08.089: E/WindowManager(2099): at android.view.ViewRoot.<init>(ViewRoot.java:259)
04-14 14:38:08.089: E/WindowManager(2099): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
04-14 14:38:08.089: E/WindowManager(2099): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
04-14 14:38:08.089: E/WindowManager(2099): at android.view.Window$LocalWindowManager.addView(Window.java:424)
04-14 14:38:08.089: E/WindowManager(2099): at android.app.Dialog.show(Dialog.java:241)
04-14 14:38:08.089: E/WindowManager(2099): at com.lcboise.lifechurch.PlayMediaActivity.ShowDialog(PlayMediaActivity.java:133)
04-14 14:38:08.089: E/WindowManager(2099): at com.lcboise.lifechurch.PlayMediaActivity.onError(PlayMediaActivity.java:237)
04-14 14:38:08.089: E/WindowManager(2099): at android.media.MediaPlayer$EventHandler.handleMessage(MediaPlayer.java:1456)
04-14 14:38:08.089: E/WindowManager(2099): at android.os.Handler.dispatchMessage(Handler.java:99)
04-14 14:38:08.089: E/WindowManager(2099): at android.os.Looper.loop(Looper.java:123)
04-14 14:38:08.089: E/WindowManager(2099): at android.app.ActivityThread.main(ActivityThread.java:3683)
04-14 14:38:08.089: E/WindowManager(2099): at java.lang.reflect.Method.invokeNative(Native Method)
04-14 14:38:08.089: E/WindowManager(2099): at java.lang.reflect.Method.invoke(Method.java:507)
04-14 14:38:08.089: E/WindowManager(2099): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:864)
04-14 14:38:08.089: E/WindowManager(2099): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:622)
04-14 14:38:08.089: E/WindowManager(2099): at dalvik.system.NativeStart.main(Native Method)