最小化应用程序并重新打开

时间:2018-05-21 16:13:03

标签: android

我收到一个RuntimeException“在调用Camera.release()之后正在使用Camera”,当我最小化应用程序然后重新打开应用程序时。该应用程序没有崩溃,所以我想知道它是否值得关注?如果是这样,我该如何解决这个问题?我在网上找不到任何有用的东西。此外,当屏幕旋转更改时,没有错误。我想这是因为相机旋转是在surfaceCreated()...

中处理的
    05-21 11:09:14.405 15474-15474/? I/zygote64: Late-enabling -Xcheck:jni
05-21 11:09:14.445 15474-15489/? E/zygote64: Failed writing handshake bytes (-1 of 14): Broken pipe
05-21 11:09:14.445 15474-15489/? I/zygote64: Debugger is no longer active
05-21 11:09:14.549 15474-15474/? I/InstantRun: starting instant run server: is main process
05-21 11:09:14.650 15474-15474/? D/TAG: onCreate() called
05-21 11:09:14.651 15474-15474/? D/TAG: onStart() called
05-21 11:09:14.656 15474-15474/? E/libc: Access denied finding property "camera.hal1.packagelist"
05-21 11:09:14.651 15474-15474/? W/ojectLightCycle: type=1400 audit(0.0:211090): avc: denied { read } for name="u:object_r:camera_prop:s0" dev="tmpfs" ino=22601 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:camera_prop:s0 tclass=file permissive=0 ppid=2713 pcomm="main" pgid=2713 pgcomm="main"
05-21 11:09:14.651 15474-15474/? D/TAG: onStart() called
05-21 11:09:14.656 15474-15474/? E/libc: Access denied finding property "camera.hal1.packagelist"
05-21 11:09:14.693 15474-15474/? D/getCameraInstance(): Camera is available
05-21 11:09:14.717 15474-15474/? D/TAG: onResume() called
05-21 11:09:14.728 15474-15586/? D/OpenGLRenderer: HWUI GL Pipeline
05-21 11:09:14.785 15474-15586/? I/Adreno: QUALCOMM build                   : 3953ab1, Ib515ec08c2
    Build Date                       : 09/27/17
    OpenGL ES Shader Compiler Version: EV031.20.00.04
    Local Branch                     : 
    Remote Branch                    : refs/tags/AU_LINUX_ANDROID_LA.UM.6.4.R1.08.00.00.309.032
    Remote Branch                    : NONE
    Reconstruct Branch               : NOTHING
05-21 11:09:14.785 15474-15586/? I/vndksupport: sphal namespace is not configured for this process. Loading /vendor/lib64/hw/gralloc.msm8998.so from the current namespace instead.
05-21 11:09:14.789 15474-15586/? I/Adreno: PFP: 0x005ff087, ME: 0x005ff063
05-21 11:09:14.792 15474-15586/? I/OpenGLRenderer: Initialized EGL, version 1.4
05-21 11:09:14.792 15474-15586/? D/OpenGLRenderer: Swap behavior 2
05-21 11:09:14.800 15474-15474/? D/Picture Size: Supported Size - Width: 5056 Height: 3792
    Supported Size - Width: 5504 Height: 3096
    Supported Size - Width: 4000 Height: 3000
    Supported Size - Width: 4608 Height: 2592
    Supported Size - Width: 3840 Height: 2160
    Supported Size - Width: 3264 Height: 2448
    Supported Size - Width: 2048 Height: 1536
    Supported Size - Width: 1920 Height: 1080
    Supported Size - Width: 1280 Height: 720
    Supported Size - Width: 720 Height: 480
    Supported Size - Width: 640 Height: 480
    Supported Size - Width: 480 Height: 320
    Supported Size - Width: 352 Height: 288
    Supported Size - Width: 320 Height: 240
    Supported Size - Width: 176 Height: 144
    Supported Size set to - Width: 5056 Height: 3792
05-21 11:09:15.050 15474-15586/? I/vndksupport: sphal namespace is not configured for this process. Loading /vendor/lib64/hw/gralloc.msm8998.so from the current namespace instead.
05-21 11:09:30.906 15474-15474/com.example.saili.ProjectLightCycle D/TAG: onPause() called
05-21 11:09:30.940 15474-15474/com.example.saili.ProjectLightCycle D/TAG: onStop() called
05-21 11:09:32.033 15474-15474/com.example.saili.ProjectLightCycle D/TAG: onStart() called
05-21 11:09:32.037 15474-15474/com.example.saili.ProjectLightCycle E/libc: Access denied finding property "camera.hal1.packagelist"
05-21 11:09:32.099 15474-15474/com.example.saili.ProjectLightCycle D/getCameraInstance(): Camera is available
05-21 11:09:32.125 15474-15474/com.example.saili.ProjectLightCycle D/TAG: onResume() called
05-21 11:09:32.146 15474-15474/com.example.saili.ProjectLightCycle E/SurfaceView: Exception configuring surface
    java.lang.RuntimeException: Camera is being used after Camera.release() was called
        at android.hardware.Camera.native_getParameters(Native Method)
        at android.hardware.Camera.getParameters(Camera.java:2027)
        at com.example.saili.ProjectLightCycle.ShowCamera.surfaceCreated(ShowCamera.java:43)
        at android.view.SurfaceView.updateSurface(SurfaceView.java:664)
        at android.view.SurfaceView.setFrame(SurfaceView.java:344)
        at android.view.View.layout(View.java:19587)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
        at android.view.View.layout(View.java:19590)
        at android.view.ViewGroup.layout(ViewGroup.java:6053)
        at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1080)
        at android.view.View.layout(View.java:19590)
        at android.view.ViewGroup.layout(ViewGroup.java:6053)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
        at android.view.View.layout(View.java:19590)
        at android.view.ViewGroup.layout(ViewGroup.java:6053)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1791)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1635)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1544)
        at android.view.View.layout(View.java:19590)
        at android.view.ViewGroup.layout(ViewGroup.java:6053)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
        at android.view.View.layout(View.java:19590)
        at android.view.ViewGroup.layout(ViewGroup.java:6053)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1791)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1635)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1544)
        at android.view.View.layout(View.java:19590)
        at android.view.ViewGroup.layout(ViewGroup.java:6053)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
        at com.android.internal.policy.DecorView.onLayout(DecorView.java:768)
        at android.view.View.layout(View.java:19590)
        at android.view.ViewGroup.layout(ViewGroup.java:6053)
        at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2488)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2204)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1390)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6754)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:966)
        at android.view.Choreographer.doCallbacks(Choreographer.java:778)
        at android.view.Choreographer.doFrame(Choreographer.java:713)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:952)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:251)
        at android.app.ActivityThread.main(ActivityThread.java:6572)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
05-21 11:09:32.168 15474-15474/com.example.saili.ProjectLightCycle D/Picture Size: Supported Size - Width: 5056 Height: 3792
    Supported Size - Width: 5504 Height: 3096
    Supported Size - Width: 4000 Height: 3000
    Supported Size - Width: 4608 Height: 2592
    Supported Size - Width: 3840 Height: 2160
    Supported Size - Width: 3264 Height: 2448
    Supported Size - Width: 2048 Height: 1536
    Supported Size - Width: 1920 Height: 1080
    Supported Size - Width: 1280 Height: 720
    Supported Size - Width: 720 Height: 480
    Supported Size - Width: 640 Height: 480
    Supported Size - Width: 480 Height: 320
    Supported Size - Width: 352 Height: 288
    Supported Size - Width: 320 Height: 240
05-21 11:09:32.169 15474-15474/com.example.saili.ProjectLightCycle D/Picture Size: Supported Size - Width: 176 Height: 144
    Supported Size set to - Width: 5056 Height: 3792
05-21 11:09:38.611 15474-15474/com.example.saili.ProjectLightCycle D/TAG: onPause() called
05-21 11:09:38.640 15474-15474/com.example.saili.ProjectLightCycle D/TAG: onStop() called
05-21 11:09:39.737 15474-15474/com.example.saili.ProjectLightCycle D/TAG: onDestroy() called

这是我的主要活动

package com.example.saili.ProjectLightCycle;


import android.content.Context;
import android.content.Intent;
import android.hardware.Camera;
import android.net.Uri;
import android.os.Environment;
import android.support.v4.view.GestureDetectorCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.Toast;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import static android.provider.MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE;

public class MainActivity extends AppCompatActivity implements GestureDetector.OnGestureListener
{
    Camera camera;
    FrameLayout frameLayout;
    ShowCamera showCamera;
    String toastString;
    private GestureDetectorCompat detector;


    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d("TAG", "onCreate() called");


    }

    @Override
    protected void onStart()
    {
        super.onStart();
        Log.d("TAG", "onStart() called");

        frameLayout = (FrameLayout) findViewById(R.id.frameLayout);

        // open the camera
        camera = getCameraInstance();
        // create a showCamera object
        showCamera = new ShowCamera(this, camera);
        // add the view to the frameLayout to diplay the camera's view on the screen
        frameLayout.addView(showCamera);

        // Auto focus the camera preview
        Camera.Parameters parameters = camera.getParameters();
        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
        camera.setParameters(parameters);

        detector = new GestureDetectorCompat(this, this);
    }

    @Override
    protected void onResume()
    {
        super.onResume();
        Log.d("TAG", "onResume() called");
    }

    @Override
    protected void onPause()
    {
        camera.setPreviewCallback(null);
        releaseCamera();

        super.onPause();
        Log.d("TAG", "onPause() called");
    }

    @Override
    protected void onStop()
    {
        super.onStop();
        Log.d("TAG", "onStop() called");
    }

    @Override
    protected void onDestroy()
    {
        super.onDestroy();
        Log.d("TAG", "onDestroy() called");
    }

    Camera.ShutterCallback mShutterCallback = new Camera.ShutterCallback()
    {
        @Override
        public void onShutter()
        {
            toastString = "Picture Captured!";
            toast(toastString);
        }
    };

    // saves the image to the external storage
    Camera.PictureCallback mPictureCallback = new Camera.PictureCallback()
    {


        @Override
      public void onPictureTaken(byte[] data, Camera camera)
      {

          File picture_file = getOutputMediaFile(MEDIA_TYPE_IMAGE);

          if (picture_file == null)
          {
              Log.d("MainActivity", "Picture_file == null");

              return;
          }
          else
          {
              Log.d("MainActivity", "Picture_file != null");

              try
              {
                  FileOutputStream fileOutputStream = new FileOutputStream(picture_file);
                  fileOutputStream.write(data);

                  Log.d("MainActivity", "Data written!");

                  fileOutputStream.close();

                  Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
                  intent.setData(Uri.fromFile(picture_file));
                  sendBroadcast(intent);

                  // this commented out method would resume camera live preview
                  //camera.startPreview();
              }
              catch (FileNotFoundException e)
              {
                  Log.d("MainActivity", "File not Found");
              }
              catch (IOException e)
              {
                  Log.d("MainActivity", "Write IOException thrown!");

                  e.printStackTrace();
              }

          }
      }
    };

    private File getOutputMediaFile(int type)
    {
        String state = Environment.getExternalStorageState();
        if (!state.equals(Environment.MEDIA_MOUNTED))
        {
            Log.d("MainActivity", "Media Not Mounted!");

            return null;
        }
        else
        {
            Log.d("MainActivity", "Media Mounted!");

            File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "WhatsThisApp");

            String picDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + File.separator + "WhatsThisApp";
            Log.d("MainActivity", picDir);

            //create the storage directory if it does not exist
            if (!mediaStorageDir.exists())
            {
                if (!mediaStorageDir.mkdirs())
                {
                    Log.d("MainActivity", "Failed to create directory");

                    return null;
                }

            }

            // create a media file name
            String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
            File mediaFile;
            if (type == MEDIA_TYPE_IMAGE)
            {
                mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");

                Log.d("MainActivity", "File name created!");
            }
            else
            {
                Log.d("MainActivity", "File name not created!");

                return null;
            }
            return mediaFile;
        }
    }

    public void captureImage(View v)
    {
        if(camera != null)
        {
            camera.takePicture(mShutterCallback,null,mPictureCallback);

            Log.d("MainActivity", "Picture Taken!");
        }
    }

    public static Camera getCameraInstance()
    {
        Camera c = null;
        try
        {
            c = Camera.open(); // Camera.open() method will open the first back facing camera on the device
                                // to access a different camera use Camera.open(int)
            Log.d("getCameraInstance()", "Camera is available");
        }
        catch (Exception e)
        {
            // Camera is not available (in use or does not exist)
            Log.d("getCameraInstance()", "Camera is not available (in use or does not exist)");
        }
        return c;
    }

    // toast method
    public void toast(String toastString)
    {
        Context context = getApplicationContext();
        CharSequence text = toastString;
        int duration = Toast.LENGTH_LONG;

        Toast toast = Toast.makeText(context, text, duration);
        toast.show();
    }

    // swip funtionality
    @Override
    public boolean onDown(MotionEvent e)
    {
        return false;
    }

    @Override
    public void onShowPress(MotionEvent e)
    {

    }

    @Override
    public boolean onSingleTapUp(MotionEvent e)
    {
        return false;
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
    {
        return false;
    }

    @Override
    public void onLongPress(MotionEvent e)
    {

    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
    {
        //Intent intent = new Intent(this, Main2Activity.class);
       // startActivity(intent);
        return true; // which says that I handled this event
    }

    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        detector.onTouchEvent(event);
        return super.onTouchEvent(event);
    }

    private void releaseCamera()
    {
        if (camera != null)
        {
            camera.release();
            camera = null;
        }
    }
}

这是我的SHowCamera课程

package com.example.saili.ProjectLightCycle;

import android.content.Context;
import android.content.res.Configuration;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.hardware.Camera;

import java.io.IOException;
import java.util.List;

public class ShowCamera extends SurfaceView implements SurfaceHolder.Callback
{
    Camera camera;
    SurfaceHolder holder;

    public ShowCamera(Context context, Camera camera)
    {
        super(context);
        this.camera = camera;
        holder = getHolder();
        holder.addCallback(this);

    }


    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
    {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder)
    {

    }

    @Override
    public void surfaceCreated(SurfaceHolder holder)
    {
        Camera.Parameters parameters = camera.getParameters();

        // finds the supported picture sizes
        List<Camera.Size> supportedPictureSizes = parameters.getSupportedPictureSizes();
        Camera.Size mSize = null;

        for (Camera.Size size : supportedPictureSizes)
        {
            mSize = size;
            Log.d("Picture Size", "Supported Size - Width: " + mSize.width + " Height: " + mSize.height);
        }

        // sets the picture size to the first available picture size higher than width 720 and height 480
        for (Camera.Size size : supportedPictureSizes)
        {
            mSize = size;
            if (mSize.width > 720 && mSize.height > 480)
            {
                break;
            }
        }
        Log.d("Picture Size", "Supported Size set to - Width: " + mSize.width + " Height: " + mSize.height);

        if(this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE)
        {
            parameters.set("orientation", "portrait");
            camera.setDisplayOrientation(90);
            parameters.setRotation(90);
        }
        else
        {
            parameters.set("Orientation", "landscape");
            camera.setDisplayOrientation(0);
            parameters.setRotation(0);
        }

        parameters.setPictureSize(mSize.width, mSize.height);
        camera.setParameters(parameters);
        try
        {
            camera.setPreviewDisplay(holder);

            camera.startPreview();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
}

2 个答案:

答案 0 :(得分:0)

根据Activity Reference当另一个活动进入前台时,将调用 onPause 方法。在用户返回活动后,将调用 onResume 方法,但不会调用 onCreate 。这样您就应该在 onResume 而不是 onCreate 上设置相机。

获取/发布任何类型的资源应始终是对称的。如果在 onStart 获取,则在 onStop realease 。如果获取 on onResume ,则发布 onPause

希望它有效!

Activity's lifecycle

答案 1 :(得分:0)

因此,对于我发布的原始问题,RuntimeException“在调用Camera.release()之后正在使用Camera”,解决方案在Logcat日志中详细说明(参见上面的日志)。我碰巧注意到在onStart()和onResume()之后我已经调用了这个错误。我说得好,当然,在Camera.release被叫之后相机正在被使用!所以,我只需要为onResume()取消调用Camera.release。

这是我最终做的事情,现在我不再在我最小化应用程序并最小化它时得到错误。可能还有另一种或更好的方法可以实现这一目标,但这对我来说是有效的。

@Override
protected void onResume()
{
    super.onResume();
    if (camera == null)
    {
        showCameraMethod();
    }
    detector = new GestureDetectorCompat(this, this);
    Log.d("TAG", "onResume() called");
}

@Override
protected void onPause()
{
    super.onPause();
    if (camera != null)
    {
        showCamera.getHolder().removeCallback(showCamera);
        camera.release(); // release the camera for other applications
        camera = null;
    }
    Log.d("TAG", "onPause() called");
}