关于java:Take picture with android camera (intent) out of memory 错误

Take picture with android camera (intent) out of memory error

下面的代码有两个问题。它只是使用相机 android 的意图拍摄照片"onclick",并在 ImageView 上显示图像。

  • 在没有离开活动的情况下拍摄两三张图片后,当我旋转显示器时,它经常会因内存不足错误而崩溃。
  • 当我第一次拍照时,它会刷新图像视图但是当我第二次或第三次拍照时......它不会刷新图片,直到我旋转屏幕
  • 我想将图片保存在内部存储器而不是外部存储器上,但我不明白该怎么做,因为我尝试了几个教程,但它卡住了相机!

    公共类 HandScryActivity 扩展 Activity {

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    private static int TAKE_PICTURE = 1;
    private MtgMatch myMatch;
    private File handFile;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.handscry);  
        // Disable screen saver
        getWindow().addFlags(LayoutParams.FLAG_KEEP_SCREEN_ON);
        // Load match
        myMatch = MtgMatch.getSingletonMtgMatch();
        handFile = new File(Environment.getExternalStorageDirectory(),"test.jpg");
        if (myMatch.getHandUri() != null) { loadPicture(); }        
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        loadPicture();
    }

    // Handles onGame clicked buttons
    public void btnHandClick(View v) {
            Button clickedButton = (Button) v;
        // according to clicked button
        switch (clickedButton.getId()) {
            case R.id.btnBackToGame:
                this.finish();
                break;
            case R.id.btnTakePicture:              
                myMatch.setHandUri(Uri.fromFile(handFile));
                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);                
                intent.putExtra(MediaStore.EXTRA_OUTPUT, myMatch.getHandUri());
                startActivityForResult(intent, TAKE_PICTURE);
                break;              
            default:
                break;
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {                    
            if (requestCode == TAKE_PICTURE) {
                // Display image
                if (resultCode == RESULT_OK) {
                    loadPicture();
            } else if (resultCode == RESULT_CANCELED) {
                // User cancelled the image capture
            } else {
                // Image capture failed, advise user
            }
        }
    }

    // Put the photo inside frame
    private void loadPicture() {
            ImageView img = (ImageView) findViewById(R.id.imgHand);
            img.setImageURI(myMatch.getHandUri());
    }

    }

  • 你有内存泄漏。旋转屏幕导致内存耗尽的原因是屏幕旋转会自动破坏 Activity 并重建它。您可以通过覆盖 onPause 和 onStart 方法并在其中放置调试语句来证明这一点,然后旋转屏幕,您会看到它们被调用。你需要了解android Activity Lifecycle。

    您有内存泄漏,因为您将这些图像的引用保存在内存中。您需要跟踪内存使用情况。当您倾斜屏幕时,旧的活动会留在内存中,并会创建一个新活动。为了让垃圾收集器收集不必要的对象,您必须确保代码中没有对它们的引用。有一些工具可以绘制应用程序的内存使用情况,以便您找出内存泄漏的位置:

    按照此页面中的说明让 MAT 告诉您内存泄漏的位置:

    android 中的内存分析工具?


    试试这个,

    在您从 onActivityResult.

    获得的图像视图解码位图上设置图像之前

    1
    2
    3
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inSampleSize = 8;
    Bitmap preview_bitmap = BitmapFactory.decodeStream(is, null, options);

    在图像视图上设置解码后。


    要解决您遇到的高内存使用率问题,您可能值得采取相机返回的文件,将其加载到位图,并使用位图工厂选项,将选项设置为使用示例尺寸。 (这会缩小图像,但很可能您不需要在 640x480 屏幕上显示 2560x1900 图像)查看本教程:http://tutorials-android.blogspot.co.il/2011/11/outofmemory-exception -when-decoding.html