Hi Android Developers,
I believe I have found a bug in the native implementation of the Android 
Media Player. My specific use case.
I am instantiating a MediaPlayer with new MediaPlayer(), the very first 
time in the onCreateView() of my VideoFragment. When I background the app, 
I destroy the fragment, but *SAVE the MEDIAPLAYER. *In* onCreateView(),* I 
have added all the appropriate callbacks for SurfaceCallbacks().

 In *surfaceCreated()*, I make sure to *mediaPlayer.setDisplay()*, as well 
on* surfaceChanged()*, making sure the surfaces are valid. When I 
background the app, I call *surfaceDestroyed(),* and I set the display to 
null. I know that is called and I have even logged it.

Also, when I background the app, i save an instance of the mediaPlayer. 
(This is to make sure I don't have to prepareAsync it anymore).

*Here is the trippy part:*
When I foreground the app, I reuse the media player. I make sure to add the 
appropriate callbacks and such again. When surfaceCreated() is called, and 
it does get called, I call* mMediaPlayer.setDisplay(holder)*. That doesn't 
actually set the display and make it visible. This will result in a *BLANK 
VIDEO SCREEN with AUDIO. This is super weird. *However, if I do 
*mMediaPlayer.setDisplay(null) 
and then mMediaPlayer.setDisplay(holder) the video shows up correctly*, and 
*THIS 
HAS TO HAPPEN ANYTIME AFTER surfaceCreated() is called otherwise *it 
doesn't work as intended and you still get a blank screen. 

@Override
public void surfaceCreated(SurfaceHolder holder) {

   if (mMediaPlayer != null) {

       mMediaPlayer.setDisplay(null);

       mMediaPlayer.setDisplay(holder);

   }

}


I believe this is a bug in the MediaPlayer native implementation. I'm not 
sure exactly what _setVideoSurface(surface) is doing since it is a NATIVE 
call.

public void setDisplay(SurfaceHolder sh) {
    mSurfaceHolder = sh;
    Surface surface;
    if (sh != null) {
        surface = sh.getSurface();
    } else {
        surface = null;
    }
    _setVideoSurface(surface);
    updateSurfaceScreenOn();
}


However, I have reason to believe it is not behaving correctly because I 
would have to call mMediaPlayer.setDisplay(null) followed by 
mMediaPlayer.setDisplay(holder) for it to work correctly. This is only 
REPRODUCIBLE IF I keep an instance of the MediaPlayer that has ALREADY BEEN 
PREPARED, as in my specific use case. If I make a completely new media 
player, and go through the async prepare process again as usual and the 
usual callback, it wouldn't occur. The only problem with this is that it is 
wasting time I don't want to spend with buffering and preparing the 
mediaPlayer again...

There is also a possibility that I am doing something wrong, but I have 
looked into this extensively and it doesn't seem to be an error on my end. 
However, I am willing to try whatever people recommend to try and fix the 
problem. To be honest, that setDisplay(null) and then setDisplay(holder) is 
a complete workaround that I'm not satisfied with.

Thanks,
Your Junior Android Developer.



-- 
You received this message because you are subscribed to the Google Groups 
"Android Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to android-developers+unsubscr...@googlegroups.com.
To post to this group, send email to android-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/android-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/android-developers/7d264526-6d1d-4e0a-b949-7a75e309b1e1%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to