10

これはよくある質問だと思いますが、このスタック トレースは別の何かが間違っていることを示しています。setDisplay(holder)内部で が呼び出されたにもかかわらず、surfaceCreatedまだ がスローされていることがわかりIllegalArgumentExceptionます。これもまれな例外ではありません。昨日は、約 3,000,000 回のクリップ ビューで約 125,000 回発生しました。mCurrentPlayerそれも正しく初期化されていることを保証できます。

作成されたサーフェス:

@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);
    }
}

スタックトレース:

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)

他に何が間違っている可能性があるかについてのアイデアはありますか? バックグラウンドスレッドで表面を破壊する可能性があり、メインスレッド(現在はによって占有されている)がブロックを終了するのをSurfaceHolder待ってから、メインスレッドで呼び出すことができます(ロックで修正できるとは思いません)?他の何か?surfaceCreatedsurfaceDestroyed

更新 - 少し掘り下げた後、「表面が解放されました」がスローされる原因がわかりました。

ここandroid_view_Surface_getSurfaceで見つけることができる参照:

これは、私の C++ 知識の欠如が痛いところです。サーフェスにロックしようとしているように見えます。それができない場合、返されるサーフェスは になりますnull。として返されるとnullIllegalArgumentExceptionスローされます。

4

2 に答える 2

4

Android VideoViews/MediaPlayers を使用して、過去にこのような問題がありました。基盤となる SurfaceView がガベージ コレクションを取得していたことが判明しました。MediaPlayer に onPreparedLister を追加し、使用中にクラスで明示的な参照を保持することで解決しました。たぶんこれが役立ちます。

于 2013-11-07T00:20:05.013 に答える