参考文献:①https://www.jianshu.com/p/586af3a2dc8d?utm_campaign=maleskine
②https://stackoverflow.com/questions/21735456/getsurfacetexture-returning-null
情况是这样的,手头有个项目B需要加入人脸识别的功能,于是新建了一个人脸识别demo项目A,调试好之后,打算移植到项目B,说干就干,经过一番辛苦修改之后终于没有报错了,将人脸识别功能全部移植到了项目B,于是高高兴兴地下载到手机运行。
然后很不幸,竟然发现屏幕预览黑屏!!!

真是诡异,在demo项目A中可是一切正常的呀!
于是检查权限,发现权限没问题,机子是华为的机子,系统版本Android5.1,只需要在加一句
<uses-permission android:name="android.permission.CAMERA" />
就行了,笔者项目中甚至做了动态权限申请,且Camera.open()方法没报错!说明权限不可能有问题。注意到Camera.open()的时候,弹出了权限提示

说明摄像头应该是打开了,整个初始化过程中完全没有报错!!
笔者项目中用的是TextureView作为预览,布局文件如下
<TextureView
android:id="@+id/single_camera_texture_preview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
然后摄像头初始化中
SurfaceTexture texture = ((TextureView) previewDisplayView).getSurfaceTexture(); mCamera.setPreviewTexture(texture);
previewView.getViewTreeObserver().addOnGlobalLayoutListener(this);
@Override
public void onGlobalLayout() {
previewView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
//previewView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
initCamera();
}
想到有可能是布局出现问题,比如被挡住了、预览视图尺寸跟摄像头不匹配等等可能,然后一一排除,还是不奏效。关键是在demoA中完全正常!
正在一筹莫展之际,注意到有一条可疑日志:
04-19 16:34:20.437 13064-13064/com.xxx D/Camera: app passed NULL surface
04-19 16:34:21.757 13064-13064/com.xxx I/RegisterAndRecognize: onCameraOpened:
这是什么鬼,信息级别是D(Debug 调试),应该没啥影响呀。但确实可疑,于是查找相关信息,发现的确是因为这个日志的原因,按照参考文献①的说法,这个日志信息是因为:camera.setPreviewDisplay(holder)方法传入的Surface不可用。
于是打断点,发现下面语句
SurfaceTexture texture = ((TextureView) previewDisplayView).getSurfaceTexture();
获取的texture竟然是null!这就难怪没法显示了!那为什么getSurfaceTexture返回null呢?文献②提到,有可能是因为TextureView没有准备好,还没有生成纹理,因此才返回null,于是按照文献②的方式,为TextureView加入SurfaceTextureListener然后在onSurfaceTextureAvailable()方法中处理初始化逻辑
preview_texture_view.setSurfaceTextureListener(this);
还是黑屏!抓狂!!!
于是又发现了日志
04-19 16:54:27.157 17813-17813/com.xxx W/TextureView: A TextureView or a subclass can only be used with hardware acceleration enabled.
注意到日志级别为W(Warnning,警告),难道是跟硬件加速有关!因为关闭了硬件加速所以TextureView异常。印象中,项目B的确是关闭了硬件加速。
打开AndroidManifest.xml,终于发现了猫腻,在application中发现:
android:hardwareAccelerated="false"
为了不影响原来工程,于是在打开摄像头的Activity中加入
android:hardwareAccelerated="true"
问题竟然奇迹般地解决了!此问题困扰笔者许久,特记录下来分享给大家,希望对大家有帮助,辛苦码字不易,喜欢的朋友点击关注,蟹蟹~
在将人脸识别功能从Demo项目移植到另一个项目时,遇到摄像头预览黑屏的问题。检查权限和布局后未找到原因。日志显示"app passed NULL surface",表明Surface不可用。发现TextureView的SurfaceTexture为null,尝试加入SurfaceTextureListener并在onSurfaceTextureAvailable()中初始化,但依然黑屏。最终,发现因硬件加速关闭导致TextureView异常,通过在Activity中开启硬件加速解决了黑屏问题。
1326

被折叠的 条评论
为什么被折叠?



