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.