SO guys I am making a Camera Application and I don't understand all the code but most of it. I copied some of the code from the net. My activity keeps force closing onSurfaceDestroyed method. I can't tell why it keeps closing when I click a picture. Because when I click a picture I start an Intent to go to a new activity. That is when the surface gets destroyed. Btw my surface is a relative layout on which my camera preview is taking place. The error is taking place in the ShowCamera class in the OnSurfaceDestroyed method. I can see the preview. The app closes when I try to click a pic.
This is my code. From my MainActivity.java I send the code below in the onCreateMethod
Camera frontCam = Camera.open(1) // 1 is for front cam
Show Camera showCamera = new ShowCamera(this, frontCam);
From the MainActivity.java I send the code below onCapture of a picture
private PictureCallback capturedIt = new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
if (bitmap == null) {
Toast.makeText(getApplicationContext(), "not taken",
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), "taken",
Toast.LENGTH_SHORT).show();
Intent viewerIntent = new Intent("com.tyrone.mirrorapp.AFTERCAPTURE");
viewerIntent.setClass(MainActivity.this, afterCapture.class);
Bundle bitmapBundle = new Bundle();
bitmapBundle.putByteArray("clickedBitmap", data);
viewerIntent.putExtras(bitmapBundle);
startActivityForResult(viewerIntent,0);
}
cameraObject.release();
}
};
This is my ShowCamera.java class below
public class ShowCamera extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder holdMe;
Camera theCamera;
public ShowCamera(Context context,Camera camera) {
super(context);
theCamera = camera;
holdMe = getHolder();
holdMe.addCallback(this);
}
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int width, int height) {
theCamera.setDisplayOrientation(90);//cz the fron cam doesn't adjust.
theCamera.startPreview();
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
theCamera.setPreviewDisplay(holder);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
theCamera.setPreviewCallback(null);
theCamera.stopPreview();
theCamera.release();
theCamera = null;
}
}
My activity keeps force closing on destroy of the activity. Any Idea what the reason could be? P.S. : I'm not entirely sure it force closes onSurfaceDestroyed. Please correct me if I am wrong. Thank You
part of my log file
11-18 20:30:31.877: I/SurfaceView(21648): Callback --> surfaceCreated
11-18 20:30:31.877: I/SurfaceView(21648): surfaceCreated callback +
11-18 20:30:31.877: D/setting preview display(21648): getting Ready
11-18 20:30:31.879: D/AndroidRuntime(21648): Shutting down VM
11-18 20:30:31.879: W/dalvikvm(21648): threadid=1: thread exiting with uncaught exception (group=0x41a00c98)
11-18 20:30:31.879: W/dalvikvm(21648): threadid=1: uncaught exception occurred
11-18 20:30:31.879: W/System.err(21648): java.lang.RuntimeException: Method called after release()
11-18 20:30:31.880: W/System.err(21648): at android.hardware.Camera.setPreviewDisplay(Native Method)
11-18 20:30:31.880: W/System.err(21648): at android.hardware.Camera.setPreviewDisplay(Camera.java:580)
11-18 20:30:31.880: W/System.err(21648): at com.tyrone.mirrorapp.ShowCamera.surfaceCreated(ShowCamera.java:66)
11-18 20:30:31.880: W/System.err(21648): at android.view.SurfaceView.updateWindow(SurfaceView.java:662)
11-18 20:30:31.881: W/System.err(21648): at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:256)
11-18 20:30:31.881: W/System.err(21648): at com.tyrone.mirrorapp.ShowCamera.onWindowVisibilityChanged(ShowCamera.java:98)
11-18 20:30:31.881: W/System.err(21648): at android.view.View.dispatchWindowVisibilityChanged(View.java:8096)
11-18 20:30:31.881: W/System.err(21648): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1110)
11-18 20:30:31.881: W/System.err(21648): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1110)
11-18 20:30:31.881: W/System.err(21648): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1110)
11-18 20:30:31.881: W/System.err(21648): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1110)
11-18 20:30:31.881: W/System.err(21648): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1110)
11-18 20:30:31.881: W/System.err(21648): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1448)
11-18 20:30:31.881: W/System.err(21648): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1192)
11-18 20:30:31.881: W/System.err(21648): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6231)
11-18 20:30:31.881: W/System.err(21648): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:788)
11-18 20:30:31.882: W/System.err(21648): at android.view.Choreographer.doCallbacks(Choreographer.java:591)
11-18 20:30:31.882: W/System.err(21648): at android.view.Choreographer.doFrame(Choreographer.java:560)
11-18 20:30:31.882: W/System.err(21648): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:774)
11-18 20:30:31.882: W/System.err(21648): at android.os.Handler.handleCallback(Handler.java:808)
11-18 20:30:31.882: W/System.err(21648): at android.os.Handler.dispatchMessage(Handler.java:103)
11-18 20:30:31.882: W/System.err(21648): at android.os.Looper.loop(Looper.java:193)
11-18 20:30:31.882: W/System.err(21648): at android.app.ActivityThread.main(ActivityThread.java:5292)
11-18 20:30:31.882: W/System.err(21648): at java.lang.reflect.Method.invokeNative(Native Method)
11-18 20:30:31.882: W/System.err(21648): at java.lang.reflect.Method.invoke(Method.java:515)
11-18 20:30:31.883: W/System.err(21648): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824)
11-18 20:30:31.883: W/System.err(21648): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640)
11-18 20:30:31.883: W/System.err(21648): at dalvik.system.NativeStart.main(Native Method)
11-18 20:30:31.883: W/dalvikvm(21648): threadid=1: calling UncaughtExceptionHandler
11-18 20:30:31.885: E/AndroidRuntime(21648): FATAL EXCEPTION: main
11-18 20:30:31.885: E/AndroidRuntime(21648): Process: com.tyrone.mirrorapp, PID: 21648
11-18 20:30:31.885: E/AndroidRuntime(21648): java.lang.RuntimeException: Method called after release()
11-18 20:30:31.885: E/AndroidRuntime(21648): at android.hardware.Camera.setPreviewDisplay(Native Method)
11-18 20:30:31.885: E/AndroidRuntime(21648): at android.hardware.Camera.setPreviewDisplay(Camera.java:580)
11-18 20:30:31.885: E/AndroidRuntime(21648): at com.tyrone.mirrorapp.ShowCamera.surfaceCreated(ShowCamera.java:66)
11-18 20:30:31.885: E/AndroidRuntime(21648): at android.view.SurfaceView.updateWindow(SurfaceView.java:662)
11-18 20:30:31.885: E/AndroidRuntime(21648): at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:256)
11-18 20:30:31.885: E/AndroidRuntime(21648): at com.tyrone.mirrorapp.ShowCamera.onWindowVisibilityChanged(ShowCamera.java:98)
11-18 20:30:31.885: E/AndroidRuntime(21648): at android.view.View.dispatchWindowVisibilityChanged(View.java:8096)
11-18 20:30:31.885: E/AndroidRuntime(21648): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1110)
11-18 20:30:31.885: E/AndroidRuntime(21648): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1110)
11-18 20:30:31.885: E/AndroidRuntime(21648): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1110)
11-18 20:30:31.885: E/AndroidRuntime(21648): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1110)
11-18 20:30:31.885: E/AndroidRuntime(21648): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1110)
11-18 20:30:31.885: E/AndroidRuntime(21648): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1448)
11-18 20:30:31.885: E/AndroidRuntime(21648): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1192)
11-18 20:30:31.885: E/AndroidRuntime(21648): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6231)
11-18 20:30:31.885: E/AndroidRuntime(21648): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:788)
11-18 20:30:31.885: E/AndroidRuntime(21648): at android.view.Choreographer.doCallbacks(Choreographer.java:591)
11-18 20:30:31.885: E/AndroidRuntime(21648): at android.view.Choreographer.doFrame(Choreographer.java:560)
11-18 20:30:31.885: E/AndroidRuntime(21648): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:774)
11-18 20:30:31.885: E/AndroidRuntime(21648): at android.os.Handler.handleCallback(Handler.java:808)
11-18 20:30:31.885: E/AndroidRuntime(21648): at android.os.Handler.dispatchMessage(Handler.java:103)
11-18 20:30:31.885: E/AndroidRuntime(21648): at android.os.Looper.loop(Looper.java:193)
11-18 20:30:31.885: E/AndroidRuntime(21648): at android.app.ActivityThread.main(ActivityThread.java:5292)
11-18 20:30:31.885: E/AndroidRuntime(21648): at java.lang.reflect.Method.invokeNative(Native Method)
11-18 20:30:31.885: E/AndroidRuntime(21648): at java.lang.reflect.Method.invoke(Method.java:515)
11-18 20:30:31.885: E/AndroidRuntime(21648): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824)
11-18 20:30:31.885: E/AndroidRuntime(21648): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640)
11-18 20:30:31.885: E/AndroidRuntime(21648): at dalvik.system.NativeStart.main(Native Method)
Your log states that the exception happens onSurfaceCreated. theCamera object is released before this callback is invoked. Please check where you release camera in your app. Maybe, you release it after you pass frontCam to ShowCamera constructor in
onCreate()
.OK, as you explained, this happens when you return to MainActivity from another one. The common practice is to open camera in
onResume(
), and release inonPause()
. It is also possible to open camera inShowCamera.surfaceCreated()
, and release (as in your code above) inShowCamera.surfaceDestroyed()
.It is recommended to open camera in a background thread, but this involves more delicate scheduling of call to
Camera.setPreviewDisplay()
.