当我第二次运行时,相机应用程序崩溃了

时间:2014-09-15 11:52:43

标签: android android-camera

我开发了相机应用程序。当我第一次运行它时,它显示预览良好,并按我想要的方式工作。但当我按下后退按钮并再次打开相机时,我的应用程序崩溃了。我添加了logcat和CameraPreview.java。请帮我解决这个问题

logcat的

09-15 16:33:04.472: D/AndroidRuntime(28048): Shutting down VM
09-15 16:33:04.472: W/dalvikvm(28048): threadid=1: thread exiting with uncaught exception (group=0x40c0e930)
09-15 16:33:04.495: E/AndroidRuntime(28048): FATAL EXCEPTION: main
09-15 16:33:04.495: E/AndroidRuntime(28048): java.lang.NullPointerException
09-15 16:33:04.495: E/AndroidRuntime(28048):    at com.gravity.innovations.qr.manager.classes.CameraPreview.surfaceCreated(CameraPreview.java:40)
09-15 16:33:04.495: E/AndroidRuntime(28048):    at android.view.SurfaceView.updateWindow(SurfaceView.java:569)
09-15 16:33:04.495: E/AndroidRuntime(28048):    at android.view.SurfaceView.access$000(SurfaceView.java:86)
09-15 16:33:04.495: E/AndroidRuntime(28048):    at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:174)
09-15 16:33:04.495: E/AndroidRuntime(28048):    at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:680)
09-15 16:33:04.495: E/AndroidRuntime(28048):    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1842)
09-15 16:33:04.495: E/AndroidRuntime(28048):    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:989)
09-15 16:33:04.495: E/AndroidRuntime(28048):    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4351)
09-15 16:33:04.495: E/AndroidRuntime(28048):    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
09-15 16:33:04.495: E/AndroidRuntime(28048):    at android.view.Choreographer.doCallbacks(Choreographer.java:562)
09-15 16:33:04.495: E/AndroidRuntime(28048):    at android.view.Choreographer.doFrame(Choreographer.java:532)
09-15 16:33:04.495: E/AndroidRuntime(28048):    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
09-15 16:33:04.495: E/AndroidRuntime(28048):    at android.os.Handler.handleCallback(Handler.java:725)
09-15 16:33:04.495: E/AndroidRuntime(28048):    at android.os.Handler.dispatchMessage(Handler.java:92)
09-15 16:33:04.495: E/AndroidRuntime(28048):    at android.os.Looper.loop(Looper.java:137)
09-15 16:33:04.495: E/AndroidRuntime(28048):    at android.app.ActivityThread.main(ActivityThread.java:5039)
09-15 16:33:04.495: E/AndroidRuntime(28048):    at java.lang.reflect.Method.invokeNative(Native Method)
09-15 16:33:04.495: E/AndroidRuntime(28048):    at java.lang.reflect.Method.invoke(Method.java:511)
09-15 16:33:04.495: E/AndroidRuntime(28048):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
09-15 16:33:04.495: E/AndroidRuntime(28048):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
09-15 16:33:04.495: E/AndroidRuntime(28048):    at dalvik.system.NativeStart.main(Native Method)
09-15 16:33:04.511: D/dalvikvm(28048): GC_CONCURRENT freed 977K, 9% free 10414K/11420K, paused 2ms+6ms, total 28ms

CameraPreview.java

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
private PreviewCallback previewCallback;
private AutoFocusCallback autoFocusCallback;

@SuppressWarnings("deprecation")
public CameraPreview(Context context, Camera camera,
                     PreviewCallback previewCb,
                     AutoFocusCallback autoFocusCb) {
    super(context);
    mCamera = camera;
    previewCallback = previewCb;
    autoFocusCallback = autoFocusCb;

    // 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.
    try {
        mCamera.setPreviewDisplay(holder);
        //mCamera.startPreview();
    } 
    catch (IOException e) {
        Log.d("DBG", "Error setting camera preview: " + e.getMessage());
    }
}

public void surfaceDestroyed(SurfaceHolder holder) {
    // Camera preview released in activity
    this.getHolder().removeCallback(this);
    mCamera.stopPreview();
    mCamera.release();
}

public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    /*
     * 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
    }

    try {
        // Hard code camera surface rotation 90 degs to match Activity view in portrait
        mCamera.setDisplayOrientation(90);

        mCamera.setPreviewDisplay(mHolder);
        mCamera.setPreviewCallback(previewCallback);
        mCamera.startPreview();
        mCamera.autoFocus(autoFocusCallback);
    } catch (Exception e){
        Log.d("DBG", "Error starting camera preview: " + e.getMessage());
    }
  }
}

,第40行是,

mCamera.setPreviewDisplay(holder);

1 个答案:

答案 0 :(得分:0)

在surfaceDestroyed中你称之为:

mCamera.release();

然后在surfaceCreated中,您可以再次使用完全相同的Camera-Object。 阅读Camera.release documentation of Camera.release的文档我怀疑,重用相同的相机对象会有效。

您确定重新创建了CameraPreview对象并传递了新的Camera-Object吗?

请注意不要使用此类注释:

@SuppressWarnings("deprecation")

这些弃用是有原因的,警告不会受到伤害!