我开发了相机应用程序。当我第一次运行它时,它显示预览良好,并按我想要的方式工作。但当我按下后退按钮并再次打开相机时,我的应用程序崩溃了。我添加了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);
答案 0 :(得分:0)
在surfaceDestroyed中你称之为:
mCamera.release();
然后在surfaceCreated中,您可以再次使用完全相同的Camera-Object。 阅读Camera.release documentation of Camera.release的文档我怀疑,重用相同的相机对象会有效。
您确定重新创建了CameraPreview对象并传递了新的Camera-Object吗?
请注意不要使用此类注释:
@SuppressWarnings("deprecation")
这些弃用是有原因的,警告不会受到伤害!