首页 > 解决方案 > Android App 使用过多内存超过 500MB

问题描述

我在该活动上使用相机套件库,应用程序中的内存使用量过多可能是什么问题?

在此处输入图像描述

这是一个使用相机套件库的相机视图活动。captureButton当用户点击并被调用时会收到相机结果,cameraView.captureImage()并将结果发送到下一个预览活动。但是当仅打开活动并且尚未捕获图像时,我看到巨大的内存使用量。

我的活动代码:

public class PSLSelfieActivity extends AppCompatActivity {

    private CameraKitView cameraView;


    private FloatingActionButton captureButton, switchCamera, useGallery;
    private String TAG = "ramiz";
    private int orientation = 0;//0=pot,1=land


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_pslselfie);

        getWindow().getDecorView().setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);


        try {


            cameraView = findViewById(R.id.camera);
            captureButton = findViewById(R.id.captureButton);


            useGallery = findViewById(R.id.useGalleryButton);


            OrientationEventListener mOrientationListener = new OrientationEventListener(
                    getApplicationContext()) {
                @Override
                public void onOrientationChanged(int orientation) {
                    PSLSelfieActivity.this.orientation = orientation;

                }
            };

            if (mOrientationListener.canDetectOrientation()) {
                mOrientationListener.enable();
            }

            captureButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    cameraView.captureImage(new CameraKitView.ImageCallback() {
                        @Override
                        public void onImage(CameraKitView cameraKitView, byte[] bytes) {
                            Intent i = new Intent(PSLSelfieActivity.this, PSLSelfiePreview.class);
                            Bitmap b = loadBitmap(bytes);
                            Log.d(TAG, "OnCaptureImage: Bitmap Size= w=" + b.getWidth() + " h=" + b.getHeight());
                            PSLSelfiePreview.inputImage = b;
                            i.putExtra("orientation", orientation);
                            i.putExtra("flipImage", true);
                            startActivity(i);
                        }
                    });
                }

            });


            useGallery.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
                    photoPickerIntent.setType("image/*");
                    startActivityForResult(photoPickerIntent, USE_GALLERY_REQUEST);

                }

            });

        } catch (Exception e) {
            e.printStackTrace();
            Toast.makeText(getContext(), "There is some error with opening camera.", Toast.LENGTH_SHORT).show();
        }


    }


    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        // Check which request we're responding to
        if (requestCode == USE_GALLERY_REQUEST) {
            // Make sure the request was successful
            if (resultCode == RESULT_OK) {

                try {
                    final Uri imageUri = data.getData();
                    final InputStream imageStream = getContentResolver().openInputStream(imageUri);
                    Intent i = new Intent(PSLSelfieActivity.this, PSLSelfiePreview.class);
                    Bitmap b = loadBitmap(imageUri);
                    Log.d(TAG, "onActivityResult: Bitmap Size= w=" + b.getWidth() + " h=" + b.getHeight());
                    PSLSelfiePreview.inputImage = b;
                    i.putExtra("orientation", 0);
                    i.putExtra("flipImage", false);
                    startActivity(i);

                } catch (IOException e) {
                    e.printStackTrace();
                    Toast.makeText(getContext(), "Cannot Load Image.", Toast.LENGTH_SHORT).show();
                } catch (OutOfMemoryError e) {
                    e.printStackTrace();
                    Toast.makeText(getContext(), "Cannot Load Image. Image too Large.", Toast.LENGTH_SHORT).show();
                }

            } else {

            }
        }

    }


    @Override
    protected void onStart() {

        cameraView.onStart();
        super.onStart();

    }

    @Override
    protected void onResume() {
        cameraView.onResume();
        super.onResume();
    }

    @Override
    protected void onPause() {
        cameraView.onPause();
        super.onPause();
    }

    @Override
    protected void onStop() {

        cameraView.onStop();
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        System.gc();
        super.onDestroy();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        cameraView.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {

            case android.R.id.home:
                onBackPressed();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }

    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        System.gc();
    }

    public Bitmap loadBitmap(byte[] bytes) {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        Bitmap b = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
        options.inSampleSize = calculateInSampleSize(options, 480, 640);
        Log.d(TAG, "loadBitmap: inSampleSize=" + options.inSampleSize);
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
    }

    public Bitmap loadBitmap(Uri imageUri) throws IOException {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        final InputStream imageStream;
        imageStream = getContentResolver().openInputStream(imageUri);
        Bitmap b = BitmapFactory.decodeStream(imageStream, null, options);
        options.inSampleSize = calculateInSampleSize(options, 480, 640);
        Log.d(TAG, "loadBitmap: inSampleSize=" + options.inSampleSize);
        options.inJustDecodeBounds = false;
        final InputStream imageStreamNew;
        imageStreamNew = getContentResolver().openInputStream(imageUri);
        Bitmap outBitmap = BitmapFactory.decodeStream(imageStreamNew, null, options);
        if (imageStream != null) {
            imageStream.close();
        }
        if (imageStreamNew != null) {
            imageStreamNew.close();
        }
        return outBitmap;
    }

    public int calculateInSampleSize(
            BitmapFactory.Options options, int reqWidth, int reqHeight) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;

        Log.d(TAG, "calculateInSampleSize: h=" + height + " - w=" + width);
        if (width > height) {
            int temp = reqHeight;
            reqHeight = reqWidth;
            reqWidth = temp;
        }
        Log.d(TAG, "calculateInSampleSize: updated h=" + height + " - w=" + width);

        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {

            final int halfHeight = height / 2;
            final int halfWidth = width / 2;

            // Calculate the largest inSampleSize value that is a power of 2 and keeps both
            // height and width larger than the requested height and width.
            while ((halfHeight / inSampleSize) >= reqHeight
                    && (halfWidth / inSampleSize) >= reqWidth) {
                inSampleSize *= 2;
            }
        }

        return inSampleSize;
    }

    private Context getContext() {
        return this;
    }
}

标签: androidmemory-leaksandroid-camera

解决方案


推荐阅读