【问题标题】:GLSurfaceView crashes on device rotation / orientation change - NullPointerExceptionGLSurfaceView 在设备旋转/方向更改时崩溃 - NullPointerException
【发布时间】:2020-04-26 08:47:47
【问题描述】:

我有一个 GLSurfaceView 可以预览相机并在纵向上正常工作。我已经开始尝试实现横向录制视频,但是当方向改变时出现奇怪的错误。

我没有覆盖OnConfigurationChanged 方法,也没有在我的清单中配置android:configChanges="screenSize|orientation",但是,在尝试以这种方式处理方向更改时,我也遇到了同样的错误。对于布局,我有纵向和横向版本(layout-land 文件夹中的横向)。我这样做的原因是在线研究似乎表明 GLSurfaceView 应该能够处理屏幕旋转。

主要问题:

  1. 上述错误的最常见原因是什么?
  2. 这是使用 GLSurface 视图处理屏幕方向更改的正确方法吗?
  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】:

    我最终使用了 OrientationListener 并在设备旋转时实现“模拟”横向体验,以避免中断相机捕捉并触发错误。所以从技术上讲,我的应用程序一直处于“纵向”状态,但是当设备旋转时 UI 会更新。

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

    Android 的方法没有解决特定用例 - 如果您想防止基于逻辑的方向更改,在我的情况下,如果用户已经开始以特定方向录制。在 Swift/IOS 中,这可以通过 shouldAutorotate 方法来实现。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多