I have an activity with a media player as a member variable.
My media player is initialized like this:
mMediaPlayer = new MediaPlayer(); 
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setDataSource(MyActivity.this, URL); 
mMediaPlayer.prepareAsync(); 
//i set a on Prepared Listener to start playing on Prepared
Everything works just fine, and then i override my activity onStop method to release the Media Player.
if(mMediaPlayer!=null){
   if(mMediaPlayer.isPlaying()){
       mMediaPlayer.stop();
   }
   mMediaPlayer.release();
   mMediaPlayer=null;
}
But after the activity has stopped i get a memory leak report from LeakCanary.
The report is like this:
MyApp.Instance->
MyApp.mLoadedApk->
LoadedApk.mReceivers->
ArrayMap.mArray->
arrayObject[].[3]->
ArrayMap.mArray->
arrayObject[][0]->
MediaPlayer.mProxyReceiver->
MediaPlayer.mProxyContext->
leaks MyActivity instance.
MyApp.Instance->
MyApp.mLoadedApk->
LoadedApk.mReceivers->
ArrayMap.mArray->
arrayObject[].[3]->
ArrayMap.mArray->
arrayObject[][0]->
MediaPlayer.mProxyReceiver->
MediaPlayer.mProxyContext->
leaks MyActivity instance.
Yes i have a MyApp class which extends Application and i am holding a reference to MyApp instance in a static field, but i never use that reference in my activity, how can i solve this leak ?
[EDIT]
Here is the code of my Activity:
public class PlayActivity extends ActionBarActivity {
private MediaPlayer mediaPlayer;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_play);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
@Override
protected void onStop() {
    super.onStop();
    if(mediaPlayer!=null){
        if(mediaPlayer.isPlaying()){
            mediaPlayer.stop();
        }
        mediaPlayer.release();
        mediaPlayer=null;
    }
}
public void playIt(View view){
    if(mediaPlayer==null){
        mediaPlayer = new MediaPlayer();
        mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp) {
                mp.start();
            }
        });
    }
    if(!mediaPlayer.isPlaying()){
        mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        try {
            mediaPlayer.setDataSource(PlayActivity.this, Uri.parse("http://www.noiseaddicts.com/samples_1w72b820/142.mp3"));
            mediaPlayer.prepareAsync();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
   }
 }
                During my tests, I found this to happen during HTTP streaming.
When I checked into the source code of MediaPlayer on the target (in my case API19), there was indeed a StreamProxy instance being set and allocated, but not released in the release method, but only in the reset method.
This worked for me:
if (mediaPlayer != null) {
    mediaPlayer.reset();
    mediaPlayer.release();
    mediaPlayer = null;
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With