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 [email protected].
To post to this group, send email to [email protected].
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.