Android MediaPlayer with MediaController: LogCat error "Activity has leaked window that was originally added here"

StackOverflow https://stackoverflow.com/questions/21678444

Question

In my Android app I'm using the standard Android MediaPlayer and MediaController classes to let the user play and pause an audio file.

Everything works fine until the Activity stops (i.e. when I call the onBackPressed() method by clicking the home button at the action bar) while the MediaController is still be shown on the screen (it's easier to reconstruct if I call show(0) on my MediaController instance, so it wouldn't hide automatically after 3 seconds). In this case the app doesn't crash, but I get an error message in my LogCat as shown below:

E/WindowManager(4153): android.view.WindowLeaked:

Activity ? has leaked window ? that was originally added here

Here's the code of my Activity (shouldn't be a problem to reconstruct it):

public class MediaPlayerTest extends Activity implements MediaPlayerControl {
private LinearLayout    mContentView; 
private MediaPlayer     mPlayer;
private MediaController mMediaController;
private Handler         mHandler = new Handler();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mContentView = (LinearLayout) getLayoutInflater().inflate(R.layout.activity_test, null); 
    setContentView(mContentView);
    getActionBar().setDisplayHomeAsUpEnabled(true);
    
    // Create the MediaPlayer
    mPlayer = new MediaPlayer();
    mPlayer.setOnPreparedListener(new OnPreparedListener() {
        public void onPrepared(MediaPlayer mp) {                
            mHandler.post(new Runnable() {
                public void run()  {
                    mMediaController.show();
                }
            }); 
        }
    });
    
    // Create the MediaController
    mMediaController = new MediaController(this);
    mMediaController.setMediaPlayer(this);
    mMediaController.setAnchorView(mContentView.findViewById(R.id.mediaControllerAnchor));

    // Initialize the MediaPlayer
    try {
        mPlayer.setDataSource(Environment.getExternalStorageDirectory() + "/Download/test.aac");
        mPlayer.prepareAsync();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

@Override
protected void onDestroy() {
    super.onDestroy();
    
    // Hide the MediaController and release the MediaPlayer
    mMediaController.hide();
    mPlayer.stop();
    mPlayer.release();  
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            super.onBackPressed();
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

[...]

LogCat says:

02-10 13:43:00.421: E/WindowManager(4153): android.view.WindowLeaked: Activity com.kirby.testproject.MediaPlayerTest has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{431a57b0 V.E..... R....... 0,0-1080,264} that was originally added here
02-10 13:43:00.421: E/WindowManager(4153):  at android.view.ViewRootImpl.<init>(ViewRootImpl.java:348)
02-10 13:43:00.421: E/WindowManager(4153):  at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:248)
02-10 13:43:00.421: E/WindowManager(4153):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
02-10 13:43:00.421: E/WindowManager(4153):  at android.widget.MediaController.show(MediaController.java:346)
02-10 13:43:00.421: E/WindowManager(4153):  at android.widget.MediaController.show(MediaController.java:306)
02-10 13:43:00.421: E/WindowManager(4153):  at com.kirby.testproject.MediaPlayerTest$1$1.run(MediaPlayerTest.java:35)
02-10 13:43:00.421: E/WindowManager(4153):  at android.os.Handler.handleCallback(Handler.java:733)
02-10 13:43:00.421: E/WindowManager(4153):  at android.os.Handler.dispatchMessage(Handler.java:95)
02-10 13:43:00.421: E/WindowManager(4153):  at android.os.Looper.loop(Looper.java:136)
02-10 13:43:00.421: E/WindowManager(4153):  at android.app.ActivityThread.main(ActivityThread.java:5017)
02-10 13:43:00.421: E/WindowManager(4153):  at java.lang.reflect.Method.invokeNative(Native Method)
02-10 13:43:00.421: E/WindowManager(4153):  at java.lang.reflect.Method.invoke(Method.java:515)
02-10 13:43:00.421: E/WindowManager(4153):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
02-10 13:43:00.421: E/WindowManager(4153):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
02-10 13:43:00.421: E/WindowManager(4153):  at dalvik.system.NativeStart.main(Native Method)

I guess I'm not doing anything magical there, so what could be the reason to get that error? I'm facing this issue for many hours now and I'd highly appreciate any help.

Was it helpful?

Solution

I've figured out that it's a better way to hide the MediaController in the onPause event.

@Override
protected void onPause() {
    // Hide the MediaController and release the MediaPlayer
    mMediaController.hide();
    mPlayer.stop();
    mPlayer.release();  

    super.onPause();
}

The error still appears on configuration changes (i.e. rotating the screen) but in my case it's good enough to prevent the Activity from recreating on configuration changes:

    <activity 
        android:name=".MediaPlayerTest" 
        android:configChanges="orientation|screenSize">
    </activity>

I'm still thinking that there's a strange behaviour (I won't call it a bug since it might be my bad) with the MediaController. But I won't put more of my time into this since it's kinda working.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top