Android 相机每次在 onResume 或 onRestart 时崩溃

Android Camera Crashes every time in onResume or onRestart

我从 android camera example. it's working but every time my application resume or restart from onPause and onStop, my application crashes. I already tried this two link1, link2 构建了一个相机应用程序,但没有任何改变。我该如何解决?

logcat 显示此消息:

2169-2169/com.exshinigami.theremembrance E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.exshinigami.theremembrance, PID: 2169
java.lang.NullPointerException
        at com.exshinigami.theremembrance.CameraPreview.surfaceCreated(CameraPreview.java:35)
        at android.view.SurfaceView.updateWindow(SurfaceView.java:572)
        at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:232)
        at android.view.View.dispatchWindowVisibilityChanged(View.java:8004)
        at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1077)
        at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1077)
        at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1077)
        at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1077)
        at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1077)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1237)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1000)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5670)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
        at android.view.Choreographer.doCallbacks(Choreographer.java:574)
        at android.view.Choreographer.doFrame(Choreographer.java:544)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
        at android.os.Handler.handleCallback(Handler.java:733)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:136)
        at android.app.ActivityThread.main(ActivityThread.java:5017)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
        at dalvik.system.NativeStart.main(Native Method)

我按照@Kevin Crain 所说的做了,我将这行代码添加到我的 surefaceCreated 中,它现在可以工作了。

if ( mCamera == null ) return;

我的相机预览 Class :

import java.io.IOException;
import android.content.Context;
import android.hardware.Camera;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

/** A basic Camera preview class */
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
    private SurfaceHolder mHolder;
    private Camera mCamera;
    private static final String TAG = "------MyCamera------";

    public CameraPreview(Context context, Camera camera) {
        super(context);
        mCamera = camera;

        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        mHolder = getHolder();
        mHolder.addCallback(this);
        // deprecated setting, but required on Android versions prior to 3.0
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    public void surfaceCreated(SurfaceHolder holder) {
        // The Surface has been created, now tell the camera where to draw the preview.
        if(mCamera == null) return;
        try {
            mCamera.setPreviewDisplay(holder);
            mCamera.startPreview();
        } catch (IOException e) {
            Log.d(TAG, "Error setting camera preview: " + e.getMessage());
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        // empty. Take care of releasing the Camera preview in your activity.
        if (mCamera != null) {
            mCamera.stopPreview();
            mCamera.setPreviewCallback(null);
            mCamera.release();
            mCamera = null;
        }
    }

    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 (mHolder.getSurface() == null) {
            // preview surface does not exist
            return;
        }

        // stop preview before making changes
        try {
            mCamera.stopPreview();
        } catch (Exception e) {
            // ignore: tried to stop a non-existent preview
        }

        // set preview size and make any resize, rotate or
        // reformatting changes here

        // start preview with new settings
        try {
            mCamera.setPreviewDisplay(mHolder);
            //mCamera.setDisplayOrientation(180);
            mCamera.startPreview();

        } catch (Exception e) {
            Log.d(TAG, "Error starting camera preview: " + e.getMessage());
        }
    }
}

在我的 MainActivity 中:

    @Override
        protected void onStop() {
            super.onStop();
            if (mPreview != null) {
                FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
                preview.removeView(mPreview);
                mPreview = null;
            }

        }

  @Override
    protected void onRestart() {
        super.onRestart();
        mCamera = getCameraInstance();    //Open rear camer
        mPreview = new CameraPreview(this, mCamera);
        preview = (FrameLayout) findViewById(R.id.camera_preview);
        preview.addView(mPreview);
    }