I am trying to create a custom camera using the Camera API. I have already addressed a lot of similar issues, but in any case, I canβt get rid of the hangs in my camera preview. Sometimes the view freezes when the activity starts, despite using a different thread. But when I try to switch to the camera, the preview image is frozen every time . In the log I received only something like this:
I/Choreographer: Skipped 41 frames! The application may be doing too much work on its main thread.
My SurfaceView is placed in the Snippet in the ViewPager action, if that matters.
My custom camera class methods:
Set display orientation:
void setCameraDisplayOrientation(int cameraId) { int rotation = getActivity().getWindowManager().getDefaultDisplay().getRotation(); int degrees = 0; switch (rotation) { case Surface.ROTATION_0: degrees = 0; break; case Surface.ROTATION_90: degrees = 90; break; case Surface.ROTATION_180: degrees = 180; break; case Surface.ROTATION_270: degrees = 270; break; } int result = 0; Camera.CameraInfo info = new Camera.CameraInfo(); Camera.getCameraInfo(cameraId, info); if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) { result = ((360 - degrees) + info.orientation); } else if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { result = ((360 - degrees) - info.orientation); result += 360; } result = result % 360; camera.setDisplayOrientation(result); }
Holder Callback Class:
class HolderCallback implements SurfaceHolder.Callback { @Override public void surfaceCreated(SurfaceHolder holder) { try { camera.setPreviewDisplay(holder); camera.startPreview(); } catch (IOException e) { e.printStackTrace(); } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Camera Handler:
private CameraHandlerThread mThread = null; private static class CameraHandlerThread extends HandlerThread { Handler mHandler = null; CameraHandlerThread() { super("CameraHandlerThread"); start(); mHandler = new Handler(getLooper()); } synchronized void notifyCameraOpened() { notify(); } void openCamera() { mHandler.post(new Runnable() { @Override public void run() { camera = Camera.open(CAMERA_ID);
Camera Opening:
private void newOpenCamera() { mThread = new CameraHandlerThread(); synchronized (mThread) { mThread.openCamera(); } }
Fragment Methods:
@Override public void onResume() { super.onResume(); newOpenCamera(); setCameraDisplayOrientation(CAMERA_ID); } @Override public void onPause() { super.onPause(); if (camera != null) camera.release(); camera = null; } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); sv = (SurfaceView) getActivity().findViewById(R.id.surfaceView); makePhotoBtn = (ImageView) getActivity().findViewById(R.id.makephotoBtn); switchCameraBtn = (ImageView) getActivity().findViewById(R.id.switchCameraBtn); holder = sv.getHolder(); holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); holderCallback = new HolderCallback(); holder.addCallback(holderCallback); rotation = getActivity().getWindowManager().getDefaultDisplay().getRotation(); makePhotoBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { camera.takePicture(null, null, new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { try { new SaveBitmap().execute(toObjects(data)); } catch (Exception e) { e.printStackTrace(); } } }); } }); switchCameraBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { swapCamera(); } }); }
And the Swap Camera method:
private void swapCamera() { if (camera != null) { camera.stopPreview(); camera.setPreviewCallback(null); camera.release(); camera = null; holder.removeCallback(holderCallback); holder = null; sv = null; sv = (SurfaceView) getActivity().findViewById(R.id.surfaceView); }
What can I do to get rid of freezes in this case? Appreciate any help!
android multithreading android-fragments camera
Big coach
source share