Android startDisplayPreview()处出现Nullpointer异常

Android startDisplayPreview()处出现Nullpointer异常,android,android-camera,Android,Android Camera,目标:在相机预览中绘制一个可重新调整大小的矩形 对于空指针异常问题,我找不到任何明确的答案。所以我希望通过发布这个问题来解决我的问题。我已经拥有的: 正确的Android清单文件(摄像头权限等) 正确的xml文件 类似问题的一个答案需要添加getBestPreviewSize()方法,我尝试了这个方法 以下是代码: Preview.java public class Preview extends SurfaceView implements SurfaceHolder.Callback {

目标:在相机预览中绘制一个可重新调整大小的矩形

对于空指针异常问题,我找不到任何明确的答案。所以我希望通过发布这个问题来解决我的问题。我已经拥有的:

  • 正确的Android清单文件(摄像头权限等)
  • 正确的xml文件
  • 类似问题的一个答案需要添加getBestPreviewSize()方法,我尝试了这个方法

    以下是代码:

Preview.java

public class Preview extends SurfaceView implements SurfaceHolder.Callback {

    private SurfaceHolder mHolder;
    private Camera mCamera;

    public Preview(Context context, Camera camera) {
        super(context);
        mCamera = camera;
        mHolder = getHolder();
        mHolder.addCallback(this);
        // mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    // without this constructor, xml which uses this class, will throw this
    // error: class cannot be instantiated
    public Preview(Context context, AttributeSet attrs) {
        super(context, attrs);

    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        // TODO Auto-generated method stub

        Camera.Parameters params = mCamera.getParameters();
        Camera.Size size = getBestPreviewSize(params, w, h);

        if (size != null) {
            params.setPreviewSize(size.width, size.height);
        }
        if (mHolder.getSurface() == null) {
            return;
        }

        mCamera.startPreview();

        try {
            mCamera.setPreviewDisplay(mHolder);
            mCamera.startPreview();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            Log.d("CameraView",
                    "Error setting camera preview: " + e.getMessage());

        }

    }

    private Size getBestPreviewSize(Parameters params, int w, int h) {
        // TODO Auto-generated method stub
        Camera.Size result = null;

        for (Camera.Size size : params.getSupportedPreviewSizes()) {
            if (size.width <= w && size.height <= h) {
                if (result == null) {
                    result = size;
                } else {
                    int resultDelta = w - result.width + h - result.height;
                    int newDelta = w - size.width + h - size.height;

                    if (newDelta < resultDelta) {
                        result = size;
                    }
                }
            }
        }
        return result;
    }

    public void onPause() {
        mCamera.release();
        mCamera = null;
    }

    @Override
    public void surfaceCreated(SurfaceHolder arg0) {
        if (mCamera == null) {
            mCamera = Camera.open();

            try {
                mCamera.setPreviewDisplay(mHolder);
                mCamera.startPreview();

            } catch (IOException e) {
                // TODO Auto-generated catch block
                Log.d("", "Error setting camera preview: " + e.getMessage());
            }
        }

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder arg0) {
        // TODO Auto-generated method stub
        if (mCamera != null) {

            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }
    }

}
编辑:LogCat

09-06 20:23:15.739: E/AndroidRuntime(2352): FATAL EXCEPTION: main
09-06 20:23:15.739: E/AndroidRuntime(2352): java.lang.NullPointerException
09-06 20:23:15.739: E/AndroidRuntime(2352):     at com.example.textrecognize.Preview.surfaceCreated(Preview.java:94)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at android.view.SurfaceView.updateWindow(SurfaceView.java:543)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at android.view.SurfaceView.access$000(SurfaceView.java:81)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:169)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:671)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1820)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1000)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4214)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at android.view.Choreographer.doCallbacks(Choreographer.java:555)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at android.view.Choreographer.doFrame(Choreographer.java:525)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at android.os.Handler.handleCallback(Handler.java:615)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at android.os.Handler.dispatchMessage(Handler.java:92)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at android.os.Looper.loop(Looper.java:137)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at android.app.ActivityThread.main(ActivityThread.java:4778)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at java.lang.reflect.Method.invokeNative(Native Method)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at java.lang.reflect.Method.invoke(Method.java:511)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at dalvik.system.NativeStart.main(Native Method)

尝试使用以下代码检查空异常:

public void surfaceCreated(SurfaceHolder arg0) {
        if (mCamera == null) {
            mCamera = Camera.open();

            // is mCamera null?
            if (mCamera == null) {
                Log.e("camera", "cannot open camera");
                return;
            }

            // is mHolder null? 
            if (mHolder == null) {
                Log.e("camera", "mHolder == null");
                mHolder = getHolder();
            }

            try {
                mCamera.setPreviewDisplay(mHolder);
                mCamera.startPreview();

            } catch (IOException e) {
                // TODO Auto-generated catch block
                Log.d("", "Error setting camera preview: " + e.getMessage());
            }
        }

    }
明白了

摄影机对象本身为空。因为我的平板电脑只有一个摄像头,所以我使用了camera.open(0)和voila

我希望在每个相机预览示例/教程/开发人员指南中都提到这一点


谢谢大家的帮助。

你能发布日志让我们知道NPE在哪里吗?mHolder为空?你把它打断了吗?
public void surfaceCreated(SurfaceHolder arg0) {
        if (mCamera == null) {
            mCamera = Camera.open();

            // is mCamera null?
            if (mCamera == null) {
                Log.e("camera", "cannot open camera");
                return;
            }

            // is mHolder null? 
            if (mHolder == null) {
                Log.e("camera", "mHolder == null");
                mHolder = getHolder();
            }

            try {
                mCamera.setPreviewDisplay(mHolder);
                mCamera.startPreview();

            } catch (IOException e) {
                // TODO Auto-generated catch block
                Log.d("", "Error setting camera preview: " + e.getMessage());
            }
        }

    }