OutOfMemory exception when loading bitmap from external storage

前端 未结 13 1701
广开言路
广开言路 2020-11-29 06:52

In my application I load a couple of images from JPEG and PNG files. When I place all those files into assets directory and load it in this way, everything is ok:

         


        
相关标签:
13条回答
  • 2020-11-29 07:13

    There are two issues here....

    • Bitmap memory isn't in the VM heap but rather in the native heap - see BitmapFactory OOM driving me nuts
    • Garbage collection for the native heap is lazier than the VM heap - so you need to be quite aggressive about doing bitmap.recycle and bitmap =null every time you go through an Activity's onPause or onDestroy
    0 讨论(0)
  • 2020-11-29 07:14

    You must not depends on the GC to recycle your bitmap memory. You must clearly recycle the bitmap when it is not needed.

    See the Bitmap method:

    void recycle() Free up the memory associated with this bitmap's pixels, and mark the bitmap as "dead", meaning it will throw an exception if getPixels() or setPixels() is called, and will draw nothing.

    0 讨论(0)
  • 2020-11-29 07:15
    • When doing a lot with bitmaps, don't debug the app - just run it. The debugger will leave memory leaks.
    • Bitmaps are very expensive. If possible, scale them down on load by creating BitmapFactory.Options and setting inSampleSize to >1.

    EDIT: Also, be sure to check your app for memory leaks. Leaking a Bitmap (having static Bitmaps is an excellent way to do that) will quickly exhaust your available memory.

    0 讨论(0)
  • 2020-11-29 07:15

    Allows inSampleSize resize the final read image. getLength() of AssetFileDescriptor allows get size of file.

    You can vary inSampleSize according to getLength() to prevent OutOfMemory like this :

    private final int MAX_SIZE = 500000;
    
    public Bitmap readBitmap(Uri selectedImage)
    {
        Bitmap bm = null;
        AssetFileDescriptor fileDescriptor = null;
        try
        {
            fileDescriptor = this.getContentResolver().openAssetFileDescriptor(selectedImage,"r");
            long size = fileDescriptor.getLength();
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inSampleSize = (int) (size / MAX_SIZE);
            bm = BitmapFactory.decodeFileDescriptor(fileDescriptor.getFileDescriptor(), null, options);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            try {
                if(fileDescriptor != null) fileDescriptor.close();
            } catch (IOException e) {}
        }
        return bm;
    }
    
    0 讨论(0)
  • 2020-11-29 07:16

    I tried all the approaches mentioned here & at other resources but I came to the inference that setting ImageView's reference to null will solve the issue:

      public Bitmap getimage(String path ,ImageView iv)
       {
        //iv is passed to set it null to remove it from external memory
        iv=null;
        InputStream stream = new FileInputStream("/mnt/sdcard/mydata/" + path);
        Bitmap bitmap = BitmapFactory.decodeStream(stream, null, null);
        stream.close();
        stream=null;
        return bitmap;
        }
    

    & you are done!

    Note:Though it may solve above problem but I would suggest you to check Tom van Zummeren 's optimized image loading.

    And also check SoftReference: All SoftReferences pointing to softly reachable objects are guaranteed to be cleared before the VM will throw an OutOfMemoryError.

    0 讨论(0)
  • 2020-11-29 07:17

    This is a fairly common issue which all of us face while loading images from the sdcard.

    The solution as I found was to use inJustDecodeBounds first while loading the image using decodeFileDescriptor . That would not actually decode the image, but give the image size. Now I can scale it appropriately(using the options) so as to resize the image for the display area. Its needed because low memory on the phone can be easily taken over by your 5MP image. This I believe is the most elegant solution.

    0 讨论(0)
提交回复
热议问题