GLSurfaceView在设备旋转方向改变时崩溃 - NullPointerException

问题描述 投票:-1回答:1

我有一个GLSurfaceView,可以预览摄像机,在纵向工作时很好。我已经开始尝试在横屏中录制视频,但是当方向发生变化时,得到一个奇怪的错误。

我没有覆盖 OnConfigurationChanged 方法,并且没有 android:configChanges="screenSize|orientation" 的配置,但当我试图以这种方式处理方向变化时,也出现了同样的错误。对于布局,我有一个纵向和横向的版本(横向在layout-land文件夹中)。我这样做的原因是在网上研究似乎表明GLSurfaceView应该能够处理屏幕旋转。

主要的问题是

  1. 造成上述错误的最常见原因是什么?
  2. 这是GLSurfaceView处理屏幕方向变化的正确方法吗?
  3. 如果不是,那是什么?

错误。

2020-04-26 18:02:24.559 6197-6197/XXX.XXX E/AndroidRuntime: FATAL EXCEPTION: main
Process: XXX.XXX, PID: 6197
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.opengl.GLSurfaceView$GLThread.surfaceCreated()' on a null object reference
    at android.opengl.GLSurfaceView.surfaceCreated(GLSurfaceView.java:557)
    at android.view.SurfaceView.updateWindow(SurfaceView.java:805)
    at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:210)
    at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:944)
    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2809)
    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1663)
    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7546)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:916)
    at android.view.Choreographer.doCallbacks(Choreographer.java:718)
    at android.view.Choreographer.doFrame(Choreographer.java:650)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:902)
    at android.os.Handler.handleCallback(Handler.java:836)
    at android.os.Handler.dispatchMessage(Handler.java:103)
    at android.os.Looper.loop(Looper.java:232)
    at android.app.ActivityThread.main(ActivityThread.java:6802)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1103)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)

布局

<?xml version="1.0" encoding="utf-8"?>

<!-- Root View -->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/mainActivityLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black"
android:clipChildren="false"
android:fitsSystemWindows="true"
tools:context="XXX.XXX.MainActivity">

<!-- AspectFrameLayout that contains the GLSurfaceView -->
<XXX.XXX.AspectFrameLayout
    android:id="@+id/cameraPreview_afl"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_alignStart="@+id/libraryButton"
    android:layout_alignParentBottom="true"
    android:layout_alignParentEnd="true"
    android:layout_below="@+id/libraryButton"
    android:layout_centerInParent="true">

    <!-- GLSurfaceView displaying camera preview -->
    <android.opengl.GLSurfaceView
        android:id="@+id/cameraPreview_surfaceView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        android:clickable="true"
        android:focusable="true"/>

</XXX.XXX.AspectFrameLayout>


<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/mainOverlay"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/transparent"
    android:clipChildren="false"
    android:fitsSystemWindows="true"
    tools:context="XXX.XXX.MainActivity">

<!-- Buttons go here to appear over the preview -->

</androidx.constraintlayout.widget.ConstraintLayout>

OnCreate方法

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_camera_capture);
    ...
}
java android opengl-es glsurfaceview
1个回答
1
投票

我最终使用了一个OrientationListener,并在设备旋转时实现了一个 "模拟 "的横向体验,以避免中断相机捕获并触发错误。因此,从技术上讲,我的应用程序一直保持在 "纵向 "状态,但当设备旋转时,UI会被更新。

我不相信这是正确的方法,并欢迎一个更好的解决方案,利用Android现有的方法来处理方向变化。

Android的方法并没有解决具体的用例--如果你想基于逻辑来防止方向变化,在我的例子中,如果用户已经开始以特定的方向进行记录。在SwiftIOS中,可以通过shouldAutorotate方法来实现。

© www.soinside.com 2019 - 2024. All rights reserved.