androidandroid-bitmapbitmapdrawable

Android BitmapDrawable results in out of memory


Basically I have 4 ImageView in the UI and I want to set image to them. Following is the related codes:

private void showPhoto() {
    // (re)set the image button's image based on our photo
    Photo p = mCrime.getPhoto();
    BitmapDrawable b = null;
    if (p != null) {
        String path = getActivity()
            .getFileStreamPath(p.getFilename()).getAbsolutePath();
        Log.i(TAG,"shown picture name is: "+p.getFilename());
//            b = PictureUtils.getScaledDrawable(getActivity(), path);


           // Log.i(TAG,"entered!");
        if (cachedImageNames.size()==0)
            cachedImageNames.add(0,path);
        else{
            boolean isExisted = false;
            for (String imagePath: cachedImageNames){
                if (imagePath.equals(path)){
                    isExisted = true;
                    break;
                    //cachedImageNames.add(0,path);

                }
            }
            if (!isExisted)
                cachedImageNames.add(0,path);
        }


    }
    mCrimes = CrimeLab.get(getActivity()).getCrimes();
//        mPhotoView.setImageDrawable(b);

    Log.i(TAG,"image names' list size is: "+cachedImageNames.size());

    if(!(cachedImageNames.size()<imageViews.size())){
        for (int i=0; i<imageViews.size(); i++){

            b= PictureUtils.getScaledDrawable(getActivity(), cachedImageNames.get(i));
            imageViews.get(i).setImageDrawable(b);
        }
    }
    else{
        for (int i=0; i<cachedImageNames.size(); i++){
            b= PictureUtils.getScaledDrawable(getActivity(), cachedImageNames.get(i));
            imageViews.get(i).setImageDrawable(b);
        }
    }

}

In the console, it is indicated that this line:

b= PictureUtils.getScaledDrawable(getActivity(),cachedImageNames.get(i));

results in such an error:

 java.lang.OutOfMemoryError: Failed to allocate a 51916812 byte allocation with 16777216 free bytes and 36MB until OOM 

I am really new to android... Any suggestion?


Solution

  • You are trying to allocate 50MB of ram on heap which is an too much for android-powered device. If this is really really necessary you can add:

      android:largeHeap="true"
    

    in the <application> part of your manifest. But this is typically a not recommended solution. Most apps should not need this and should instead focus on reducing their overall memory usage for improved performance. Enabling this also does not guarantee a fixed increase in available memory, because some devices are constrained by their total available memory.


    Proper solution:

    You need to look into how many images you are opening and how big they are. Note that a very common misconception is that people usually assume that the file size is what is being used in the memory. This is a very wrong assumption. PNGs, JPGs and etc are compressed format. When you load an image on your device each pixel is 4 bytes. If you have a 2000x2000 pixel image, when loaded, it consumes 16MB of RAM - which is typically a high limit for typical (non-game) apps.