NullPointerException in SurfaceView.onAttachedToWindow(Surfa



我从SurfaceView.onAttachedToWindow得到这个异常。它看起来像SurfaceView试图引用mParent,但它是空的。有人知道为什么父不会被设置,但onAttachedToWindow将被调用?

我正在使用SurfaceView进行相机预览。我有一个ViewGroup,从活动的根视图添加/删除。在ViewGroup内部是一个SurfaceView和一个WebView。

下面是ViewGroup的代码:http://pastebin.com/eSyZ3v3P,下面是显示/隐藏相机的代码:http://pastebin.com/5iaEFCQr

任何帮助都将非常感激。

下面是完整的堆栈跟踪:
java.lang.NullPointerException
    at android.view.SurfaceView.onAttachedToWindow(SurfaceView.java:207)
    at android.view.View.dispatchAttachedToWindow(View.java:11755)
    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1199)
    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:998)
    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4212)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
    at android.view.Choreographer.doCallbacks(Choreographer.java:555)
    at android.view.Choreographer.doFrame(Choreographer.java:525)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
    at android.os.Handler.handleCallback(Handler.java:615)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4745)
    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:786)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
    at dalvik.system.NativeStart.main(Native Method)

—edit—

对不起,我忘了说,我不知道重现异常的步骤。每次我运行应用程序的代码工作,但我得到这些异常从三星Galaxy Tab 3发送到我的记录器。这个问题并不是始终如一的。

我相信你的错误是因为你在这一行使用了一个过时的视图:

setPreviewDisplay(this.surfaceView.getHolder())

在这一行中,当它崩溃时,surfaceView不再有效。你应该使用surfaceChanged/surfaceCreated返回的SurfaceHolder。

这也是我的bug的来源。

一般

:

当您试图将视图(预览)附加到不再存在的窗口时,可能会发生此错误。例如,你有一些长时间运行的代码(打开相机),然后你附加视图,手机已经旋转(旧的上下文)或另一个应用程序正在显示(所以它是无效的附加到看不见的视图),或者锁屏是打开的,等等。

避免这种情况的一种方法是确保在您尝试附加视图之前您的Activity有一个可见窗口。我希望我有更多的细节告诉你怎么做。

一个可能的问题是你正在做Camera.open(),这可能需要一些时间,特别是在某些设备上,在你调用addView()之前,所以也许当你绕过addView()时,窗口不可用。考虑在后台线程上执行Camera.open(),当所有这些都完成后,执行addView()。

我看到你有几个线程在UI线程上运行。你要确保这些在addView之前都完成了。

我不知道是什么原因,但我能想到的只有一个工作:

    this.surfaceView = new SurfaceView(customContext) {
        /* (non-Javadoc)
         * @see android.view.SurfaceView#onAttachedToWindow()
         */
        @Override
        protected void onAttachedToWindow() {
            if(this.getParent() != null)
                super.onAttachedToWindow();
        }
    };

不能测试它,看看它是否会产生更多的问题,或者只是修复这个。

我知道这很粗俗,但我想写下来也无妨。

试试吧,风险自负!

在CameraPluginView类的构造函数中,传递customContext

           this.surfaceView = new SurfaceView(getContext());

代替前面的调用,试试这个构造函数:

         SurfaceView(Context context, AttributeSet attrs)

您的mParent可能为空,因为View.java中的assignView可能未被调用。检查这个。检查错误的简单方法-使用TextView创建一个示例项目并逐步检查调试(在assignView()方法和onAttachedToWindow()中设置断点),您将看到问题所在。

最新更新