Android相机:应用程序传递NULL面 [英] Android Camera: app passed NULL surface
问题描述
我发现在这几个问题,但因此在这里没有答案的希望有人可能有一些见解。当我尝试换镜头我拨打以下swapCamera功能。然而,相机preVIEW只是冻结(应用程序不结冰虽然只是直播相机preVIEW)。
当我打开应用程序首次一切工作就好了。不过我注意到一些有趣的事情。当我注销_surfaceHolder对象的memoryaddress(即我SurfaceHolder对象),它给了我一个值,但每当我查询该值之后,应用程序已完成启动和一切,内存地址已经更改。
再者,它给了我,当我swapCamera非常混乱的错误。我登出_surfaceHolder之前我把它传递到相机的 _camera.set previewDisplay(_surfaceHolder);
之前它的通过不是null。
任何帮助是极大AP preciated。
我注意到一些有趣的行为
公共类相机preVIEW延伸SurfaceView实现SurfaceHolder.Callback
{
私人SurfaceHolder _surfaceHolder;
私人相机_camera;
布尔_isBackFacing; 公共摄像头preVIEW(上下文的背景下,相机摄像头){
超级(上下文);
_camera =摄像头;
_isBackFacing = TRUE; //安装SurfaceHolder.Callback所以我们得到通知时,
//创建下垫面和销毁。
_surfaceHolder = getHolder();
_surfaceHolder.addCallback(本);
} 无效refreshCamera()
{
尝试{
_camera.set previewDisplay(_surfaceHolder);
_camera.start preVIEW();
}赶上(IOException异常五){
Log.d(iCamera,错误设置相机preVIEW:+ e.getMessage());
}
} 公共无效surfaceCreated(SurfaceHolder持有人)
{
//表面有被创建,现在告诉相机在哪里画preVIEW。
refreshCamera();
} 公共无效surfaceDestroyed(SurfaceHolder持有人)
{
//空。参加你的活动释放相机preVIEW照顾。
_surfaceHolder.removeCallback(本);
} 公共无效surfaceChanged(SurfaceHolder架,INT格式,诠释W,INT高)
{
//如果你的preVIEW可以更改或旋转,把这些事件的关心在这里。
//确保调整或重新格式化之前停止preVIEW。 如果(_surfaceHolder.getSurface()== NULL){
// preVIEW表面不存在
返回;
} 尝试{
_camera.stop preVIEW();
}赶上(例外五){
//忽略:试图停止不存在的preVIEW
} //设置preVIEW大小并进行缩放,旋转或
//格式化改变了她的
_camera.setDisplayOrientation(90); // _startPoint preVIEW新设置
refreshCamera();
} 公共无效swapCamera()
{
相机凸轮=无效;
INT cameraCount = Camera.getNumberOfCameras();
Camera.CameraInfo cameraInfo =新Camera.CameraInfo();
_camera.stop preVIEW();
_camera.release();
的for(int i = 0; I< cameraCount;我++)
{
Camera.getCameraInfo(ⅰ,cameraInfo);
如果(cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT&放大器;&安培; _isBackFacing == true)而
{
尝试
{
_camera = Camera.open(ⅰ); }赶上(RuntimeException的E)
{
Log.e(错误,摄像头无法打开:+ e.getLocalizedMessage());
}
} 如果(cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK&放大器;&安培; _isBackFacing ==假)
{
尝试
{
_camera = Camera.open(ⅰ);
}赶上(RuntimeException的E)
{
Log.e(错误,摄像头无法打开:+ e.getLocalizedMessage());
}
}
} _isBackFacing = _isBackFacing!;
refreshCamera();
}
}
所以,经过多次调试和挖掘我发现罪魁祸首是onResume功能。
在这,我是'耳目一新'相机变量的情况下,它得到了上下文切换之间丢失。
公共无效onResume()
{
super.onResume();
_camera preVIEW =新相机preVIEW(getActivity());
}
必须重新创建
这是造成我surfaceHolder。我不知道是什么原因会导致空的,但我想是因为我创建了一个SurfaceHolder的新实例,内部的Android code是保持老(现为空)SurfaceHolder的参考。通过从onResume删除我的刷新(即重新实例)调用的问题是固定的。
该错误是误导我想是因为它说一个空的表面传递,但是那是因为我认为它保持引用一个空surfaceHolder即使你创造了一个新的,并通过在(似乎使用旧的,现在空1反正)。所以,如果你得到这个错误,请检查你是不是重新创建surfaceHolder,并通过它
I've found several questions on this but no answers so here's hoping someone might have some insight. When I try to swap the camera I call the swapCamera function below. However the camera preview just freezes (the app is not frozen though just the live camera preview).
When I open the app for the first time everything works just fine. However I noticed something interesting. When I log out the memoryaddress of the _surfaceHolder object (i.e. my SurfaceHolder object) it gives me one value, but whenever I query that value after the app has finished launching and everything, that memory address has changed.
Further still, the error it gives me when I swapCamera is very confusing. I logged out _surfaceHolder before I passed it to the camera in _camera.setPreviewDisplay(_surfaceHolder);
and it is NOT null before it's passed in.
Any help is greatly appreciated.
I've noticed some interesting behaviour
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback
{
private SurfaceHolder _surfaceHolder;
private Camera _camera;
boolean _isBackFacing;
public CameraPreview(Context context, Camera camera) {
super(context);
_camera = camera;
_isBackFacing = true;
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
_surfaceHolder = getHolder();
_surfaceHolder.addCallback(this);
}
void refreshCamera()
{
try {
_camera.setPreviewDisplay(_surfaceHolder);
_camera.startPreview();
} catch (IOException e) {
Log.d("iCamera", "Error setting camera preview: " + e.getMessage());
}
}
public void surfaceCreated(SurfaceHolder holder)
{
// The Surface has been created, now tell the camera where to draw the preview.
refreshCamera();
}
public void surfaceDestroyed(SurfaceHolder holder)
{
// empty. Take care of releasing the Camera preview in your activity.
_surfaceHolder.removeCallback(this);
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h)
{
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
if (_surfaceHolder.getSurface() == null){
// preview surface does not exist
return;
}
try {
_camera.stopPreview();
} catch (Exception e) {
// ignore: tried to stop a non-existent preview
}
// set preview size and make any resize, rotate or
// reformatting changes her
_camera.setDisplayOrientation(90);
// _startPoint preview with new settings
refreshCamera();
}
public void swapCamera()
{
Camera cam = null;
int cameraCount = Camera.getNumberOfCameras();
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
_camera.stopPreview();
_camera.release();
for (int i = 0; i < cameraCount; i++)
{
Camera.getCameraInfo(i,cameraInfo);
if(cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT && _isBackFacing == true)
{
try
{
_camera = Camera.open(i);
}catch (RuntimeException e)
{
Log.e("Error","Camera failed to open: " + e.getLocalizedMessage());
}
}
if(cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK && _isBackFacing == false)
{
try
{
_camera = Camera.open(i);
}catch (RuntimeException e)
{
Log.e("Error","Camera failed to open: " + e.getLocalizedMessage());
}
}
}
_isBackFacing = !_isBackFacing;
refreshCamera();
}
}
So after much debugging and digging what I found to be the culprit was the onResume function.
In it, I was 'refreshing' the camera variable in case it got lost between context switching.
public void onResume()
{
super.onResume();
_cameraPreview = new CameraPreview(getActivity());
}
This was causing my surfaceHolder to be created anew. I'm not exactly sure why it would cause a null, but I think because I created a new instance of a SurfaceHolder, the internal Android code was keeping a reference to the old (now null) SurfaceHolder. By removing my 'refresh' (i.e. reinstantiating) call from onResume the problem was fixed.
The error is misleading I think because its saying a null surface was passed but thats because I think its keeping a reference to a null surfaceHolder even if you created a new one and passed that in (it seems to use the OLD now null one anyways). So if you get this error, check that you aren't re-creating the surfaceHolder and passing it in.
这篇关于Android相机:应用程序传递NULL面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!