Comment se débarrasser de la caméra gelée (SurfaceView)?

J'essaie de créer une caméra personnalisée utilisant Camera API. J'ai déjà examiné beaucoup de questions similaires, mais de toute façon, je ne peux pas me débarrasser des glaçons dans mon aperçu de la caméra. Parfois, l'aperçu s'arrête lorsque l'activité a commencé, malgré l'utilisation d'un autre thread. Mais lorsque j'essaie de changer pour regarder la caméra, l'image de prévisualisation se congèle à chaque fois . Dans log i J'ai seulement quelque chose comme ça:

I/Choreographer: Skipped 41 frames! The application may be doing too much work on its main thread. 

Mon SurfaceView est placé dans Fragment dans l'activité ViewPager s'il est important.

  • Comment utiliser crontab dans Android?
  • Android - Utilisation de la méthode à partir d'un service dans une activité?
  • Définition de styles globaux pour les vues dans Android
  • Envoi d'une chaîne via Bluetooth depuis un PC en tant que client vers un mobile en tant que serveur
  • Vue en liste avec des groupes dans Android
  • Fragment transition d'élément partagé avec add () au lieu de replace ()?
  • Mes méthodes de classe de caméra personnalisée:

    Définir l'orientation de l'affichage:

     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); } 

    Classe de rappel du titulaire:

     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) { // TODO Auto-generated method stub if (mIsPreviewing) { camera.stopPreview(); mIsPreviewing = false; } if (camera != null) { Camera.Parameters parameters = camera.getParameters(); Camera.Size bestSize = getBestPreviewSize(width, height, parameters); if (bestSize != null) { parameters.setPreviewSize(bestSize.width, bestSize.height); camera.setParameters(parameters); Toast.makeText( getActivity().getApplicationContext(), "Оптимальный размер: " + String.valueOf(bestSize.width) + " : " + String.valueOf(bestSize.height), Toast.LENGTH_LONG).show(); } try { camera.setPreviewDisplay(holder); camera.startPreview(); mIsPreviewing = true; // camera.autoFocus(autoFocusCallback); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } private Camera.Size getBestPreviewSize(int width, int height, Camera.Parameters parameters) { Camera.Size bestSize = null; List<Camera.Size> sizeList = parameters.getSupportedPreviewSizes(); bestSize = sizeList.get(0); for (int i = 1; i < sizeList.size(); i++) { if ((sizeList.get(i).width * sizeList.get(i).height) > (bestSize.width * bestSize.height)) { bestSize = sizeList.get(i); } } return bestSize; } @Override public void surfaceDestroyed(SurfaceHolder holder) { } } 

    Télécopieur:

     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); //set camera to continually auto-focus Camera.Parameters params = camera.getParameters(); //*EDIT*//params.setFocusMode("continuous-picture"); //It is better to use defined constraints as opposed to String, thanks to AbdelHady // params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); // camera.setParameters(params); //STEP #1: Get rotation degrees Camera.CameraInfo info = new Camera.CameraInfo(); Camera.getCameraInfo(Camera.CameraInfo.CAMERA_FACING_BACK, info); int degrees = 0; switch (rotation) { case Surface.ROTATION_0: degrees = 0; break; //Natural orientation case Surface.ROTATION_90: degrees = 90; break; //Landscape left case Surface.ROTATION_180: degrees = 180; break;//Upside down case Surface.ROTATION_270: degrees = 270; break;//Landscape right } int rotate = (info.orientation - degrees + 360) % 360; //STEP #2: Set the 'rotation' parameter params.setRotation(rotate); camera.setParameters(params); notifyCameraOpened(); camera.startPreview(); } }); try { wait(); } catch (InterruptedException e) { Log.d(TAG, "openCamera: Cannot open Camera"); } } } 

    Ouverture de la caméra:

     private void newOpenCamera() { mThread = new CameraHandlerThread(); synchronized (mThread) { mThread.openCamera(); } } 

    Méthodes de fragmentation:

      @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(); } }); } 

    Méthode de la caméra Swap:

      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); } //swap the id of the camera to be used if (CAMERA_ID == Camera.CameraInfo.CAMERA_FACING_FRONT) { CAMERA_ID = 0; } else { CAMERA_ID = 1; } newOpenCamera(); } 

    Que puis-je faire pour éliminer le gel dans ce cas? Appréciez toute aide!

  • Comment faire un style de texte dans le menu de débordement d'action sur le périphérique avec Android> 4.0 et le bouton de matériel?
  • Créer et exécuter une application via Gradle et Android Studio est plus lent que via Eclipse
  • Existe-t-il une raison d'utiliser le modèle Observer sur un récepteur de diffusion?
  • Comment exécuter ou déboguer sur un téléphone Android au lieu d'un émulateur?
  • BackgroundColorSpan avec rembourrage vertical supplémentaire
  • SearchView dans ActionBar - problèmes avec le bouton * Up *
  • coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.