Android相机:应用程序传递NULL面 [英] Android Camera: app passed NULL surface

查看:1240
本文介绍了Android相机:应用程序传递NULL面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现在这几个问题,但因此在这里没有答案的希望有人可能有一些见解。当我尝试换镜头我拨打以下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的新实例,内部的Andr​​oid 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆