我有一个GLSurfaceView,可以预览摄像机,在纵向工作时很好。我已经开始尝试在横屏中录制视频,但是当方向发生变化时,得到一个奇怪的错误。
我没有覆盖 OnConfigurationChanged
方法,并且没有 android:configChanges="screenSize|orientation"
的配置,但当我试图以这种方式处理方向变化时,也出现了同样的错误。对于布局,我有一个纵向和横向的版本(横向在layout-land文件夹中)。我这样做的原因是在网上研究似乎表明GLSurfaceView应该能够处理屏幕旋转。
主要的问题是
错误。
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);
...
}
我最终使用了一个OrientationListener,并在设备旋转时实现了一个 "模拟 "的横向体验,以避免中断相机捕获并触发错误。因此,从技术上讲,我的应用程序一直保持在 "纵向 "状态,但当设备旋转时,UI会被更新。
我不相信这是正确的方法,并欢迎一个更好的解决方案,利用Android现有的方法来处理方向变化。
Android的方法并没有解决具体的用例--如果你想基于逻辑来防止方向变化,在我的例子中,如果用户已经开始以特定的方向进行记录。在SwiftIOS中,可以通过shouldAutorotate方法来实现。