I know this is a common question, however this stack trace shows something else is wrong. You can see that even though setDisplay(holder)
is called inside of surfaceCreated
it still throws IllegalArgumentException
. This isn't a rare exception either, yesterday happening ~125,000 times in ~3,000,000 clip views. I can assure you that mCurrentPlayer
is initialized correctly as well.
surfaceCreated:
@Override
public void surfaceCreated(SurfaceHolder holder) {
mIsSurfaceCreated = true;
mCurrentPlayer.setDisplay(holder);
}
surfaceDestroy:
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mIsSurfaceCreated = false;
// Could be called after player was released in onDestroy.
if (mCurrentPlayer != null) {
mCurrentPlayer.setDisplay(null);
}
}
Stacktrace:
java.lang.IllegalArgumentException: The surface has been released
at android.media.MediaPlayer._setVideoSurface(Native Method)
at android.media.MediaPlayer.setDisplay(MediaPlayer.java:660)
at com.xxx.xxx.view.VideoPlayerView.surfaceCreated(VideoPlayerView.java:464)
at android.view.SurfaceView.updateWindow(SurfaceView.java:543)
at android.view.SurfaceView.access$000(SurfaceView.java:81)
at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:169)
at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:590)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1644)
at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2505)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:4945)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
Any ideas on what else could be going wrong? Is SurfaceHolder
potentially destroying the surface on a background thread and then waiting for the main thread (currently occupied by surfaceCreated
) to finish it's block before it can call surfaceDestroyed
on the main thread (which I don't even think locks can fix)? Something else?
Update -- After drilling down a little farther I found out what causes "The surface has been released" to be thrown:
Which references android_view_Surface_getSurface
which can be found here:
This is where my lack of C++ knowledge hurts, it's looking like it's trying to lock onto the surface, and if it can't the surface returned will be null
. Once it gets returned as null
, IllegalArgumentException
will be thrown.