Android 的 Surface class 给我一个 "already connected" 错误和一个 IllegalArgumentException

Android's Surface class gives me an "already connected" error, and a IllegalArgumentException

我正在打电话:

mSurface.lockCanvas(null);

null是可以接受的参数给lockCanvas,表示需要更新整个屏幕

我正在使用的表面正在传递给我,获取它的代码通过:

new Surface(mPlaybackView.getSurfaceTexture());

mPlaybackView是从Resources中抓取的TextureView。调用 lockCanvas(null) 时,我得到以下信息:

BufferQueueProducer: [unnamed-6903-1] connect(P): already connected (cur=3 req=2)

java.lang.IllegalArgumentException at android.view.Surface.nativeLockCanvas (Native Method).

我很困惑,因为我还在学习 canvas 和表面等等

这里有什么明显的错误吗?

编辑:这是堆栈跟踪。

    11-19 09:45:28.075 3319-3319/com.example.eschjen.nov15test D/Jenny: inside try, surface is: Surface(name=android.graphics.SurfaceTexture@10e80e42)/@0x3bc8b489
11-19 09:45:28.086 3319-3319/com.example.eschjen.nov15test E/BufferQueueProducer: [unnamed-3319-0] connect(P): already connected (cur=3 req=2)
11-19 09:45:28.087 3319-3319/com.example.eschjen.nov15test E/Jenny: Exception caught: 
                                                                    java.lang.IllegalArgumentException
                                                                        at android.view.Surface.nativeLockCanvas(Native Method)
                                                                        at android.view.Surface.lockCanvas(Surface.java:255)
                                                                        at com.example.eschjen.nov15test.MediaCodecWrapper.surfaceRender(MediaCodecWrapper.java:469)
                                                                        at com.example.eschjen.nov15test.MediaCodecWrapper.access0(MediaCodecWrapper.java:41)
                                                                        at com.example.eschjen.nov15test.MediaCodecWrapper.outputSample(MediaCodecWrapper.java:338)
                                                                        at com.example.eschjen.nov15test.MediaCodecWrapper.popSampleJenny(MediaCodecWrapper.java:345)
                                                                        at com.example.eschjen.nov15test.MainActivity.onTimeUpdate(MainActivity.java:183)
                                                                        at android.animation.TimeAnimator.animationFrame(TimeAnimator.java:27)
                                                                        at android.animation.ValueAnimator.doAnimationFrame(ValueAnimator.java:1248)
                                                                        at android.animation.ValueAnimator$AnimationHandler.doAnimationFrame(ValueAnimator.java:659)
                                                                        at android.animation.ValueAnimator$AnimationHandler.run(ValueAnimator.java:682)
                                                                        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
                                                                        at android.view.Choreographer.doCallbacks(Choreographer.java:580)
                                                                        at android.view.Choreographer.doFrame(Choreographer.java:549)
                                                                        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
                                                                        at android.os.Handler.handleCallback(Handler.java:739)
                                                                        at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                        at android.os.Looper.loop(Looper.java:135)
                                                                        at android.app.ActivityThread.main(ActivityThread.java:5221)
                                                                        at java.lang.reflect.Method.invoke(Native Method)
                                                                        at java.lang.reflect.Method.invoke(Method.java:372)
                                                                        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
                                                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
11-19 09:45:28.087 3319-3319/com.example.eschjen.nov15test D/Jenny: done trying
11-19 09:45:28.088 3319-3319/com.example.eschjen.nov15test D/Jenny: done being synchronized.

我认为 mPlaybackViewTextureView。如果 'rect' 矩形无效,Surface.lockCanvas(rect) 可以抛出 IllegalArgumentException

E/BufferQueueProducer: [unnamed-3319-0] connect(P): already connected (cur=3 req=2)

来自TextureView中的documentation

A TextureView's SurfaceTexture can be obtained either by invoking getSurfaceTexture() or by using a TextureView.SurfaceTextureListener. It is important to know that a SurfaceTexture is available only after the TextureView is attached to a window (and onAttachedToWindow() has been invoked.) It is therefore highly recommended you use a listener to be notified when the SurfaceTexture becomes available. It is important to note that only one producer can use the TextureView. For instance, if you use a TextureView to display the camera preview, you cannot use lockCanvas() to draw onto the TextureView at the same time.

您需要确保与此 TextureView 关联的 SurfaceTexture 可用于呈现。您可以使用 TextureView.isAvailable() 来确认。

我正在用相同的 TextureViewSurfaceTexture 切换相机。同样的错误 already connected 对我来说 surface.release 有效。一些代码片段供您参考:

启动相机时执行此操作

if (previewSurfaceTarget == null) previewSurfaceTarget = new Surface(mPreviewSurfaceTexture);

重启前执行此操作

if (null != mCameraDevice) {
    mCameraDevice.close();
    mCameraDevice = null;
    mCameraIsOpen = false;
}

if (previewSurfaceTarget != null)
previewSurfaceTarget.release();
previewSurfaceTarget = null;