Out of Memory Error ImageView issue
To add on Ken's answer, which is a solid piece of code, I thought I'd knock it down after he set it up:
if(imageView != null) { ((BitmapDrawable)imageView.getDrawable()).getBitmap().recycle(); } imageView = (ImageView) view.findViewById(R.id.imageView); imageView.setImageResource(resID);
NOTE: This won't work if you are trying to swap an image you already recycled. You'll get something like this in LOGCAT
Canvas: trying to use a recycled bitmap
So what I do now if I don't have to load a bunch of different images asynchronously, I simply put this in onDestroy when dealing with fragments and large background images:
@Overridepublic void onDestroy() { super.onDestroy(); imageView.setImageDrawable(null);}
Use
((BitmapDrawable)imageView.getDrawable()).getBitmap().recycle();
Before change to new image!!
For those using the Glide image loading library, who are still running into these OutOfMemory Exception
issues, there're many things you can do to make Glide
use less memory and hopefully fix your problem. Here are a few of them:
Don't use
android:scaleType="fitXY"
inside of yourImageView
. So if you'reImageView
looks like this:<ImageView android:id="@android:id/icon" android:layout_width="@dimen/width" android:layout_height="@dimen/height" android:adjustViewBounds="true" android:scaleType="fitXY" <!-- DON'T USE "fitXY"! -->/>
Change the
ImageView
to use a differentandroid:scaleType
, preferably:fitCenter
orcenterCrop
.- Don't use
wrap_content
in yourImageView
, instead usematch_parent
or specify thewidth
/height
explicitly using a size indp
. If you really insist on usingwrap_content
in yourImageView
, at least set aandroid:maxHeight
/android:maxWidth
. - Turn off animations with:
dontAnimate()
on yourGlide.with()...
request. If you're loading lots of potentially large images (as you would in a list/grid), specify a
thumbnail(float sizeMultiplier)
load in your request. Ex:Glide.with(context) .load(imageUri) .thumbnail(0.5f) .dontAnimate() .into(iconImageView);
Temporarily lower
Glide
's memory footprint during certain phases of your app by using:Glide.get(context).setMemoryCategory(MemoryCategory.LOW)
.- Only cache in memory if you need to, you can turn it off with:
skipMemoryCache(true)
on yourGlide.with()...
request. This will still cache the images to disk, which you'll probably want since you're foregoing the in-memory cache. - If you're loading a
Drawable
from your local resources, make sure that the image you're trying to load ISN'T SUPER HUGE. There are plenty of image compression tools available online. These tools will shrink the sizes of your images while also maintaining their appearance quality. - If loading from local resources use
.diskCacheStrategy(DiskCacheStrategy.NONE)
. Hook into the
onTrimMemory(int level)
callback that Android provides to trim theGlide
cache as needed. Ex.@Overridepublic void onTrimMemory(int level){ super.onTrimMemory(level); Glide.get(this).trimMemory(level);}
If displaying images in a
RecyclerView
you can explicitly clearGlide
when views are recycled, like so:@Overridepublic void onViewRecycled(MyAdapter.MyViewHolder holder){ super.onViewRecycled(holder); Glide.clear(holder.imageView);}
- If this is still occurring, even after you've "tried everything", the problem might be your application (GASP!), and
Glide
is just the one thing that's pushing it to theOutOfMemory Exception
zone... So be sure you don't have any memory leaks in your application.Android Studio
provides tools for identifying memory consumption issues in you app. - Lastly check the issue page on Glide's GitHub, for similar issues that may provide insight into fixing your problem(s). The repo is managed really well and they're very helpful.