Edited:
glide
to load images. I\'m getting Out of
Probably a different approach can be taken to resolve this. To achieve this you can use a different ImageAdapter with
Glide.with(mActivity).loadFromMediaStore(_imageInfo.getmUri())
this does not crash being using MediaStoreThumbFetcher
To have more control over the load do the following using Glide v4
// usage:
Glide.with(mActivity).load(_imageInfo)....
// in GlideModule.registerComponents
registry.prepend(ImageInfo.class, ImageInfo.class, new UnitModelLoader.Factory<ImageInfo>());
registry.prepend(ImageInfo.class, Bitmap.class, new ImageInfoBitmapDecoder(context));
class ImageInfoBitmapDecoder implements ResourceDecoder<ImageInfo, Bitmap> {
private final ContentResolver contentResolver;
private final BitmapPool pool;
public ImageInfoBitmapDecoder(Context context) {
this.contentResolver = context.getContentResolver();
this.pool = Glide.get(context).getBitmapPool();
}
@Override public boolean handles(ImageInfo source, Options options) { return true; }
@Override public @Nullable Resource<Bitmap> decode(ImageInfo source, int width, int height, Options options) {
Bitmap thumb = Thumbnails.getThumbnail(contentResolver, source.getmId(), Thumbnails.MINI_KIND, null);
return BitmapResource.obtain(thumb, pool);
}
}
Using following API's we can figure out free memory left out and size of the bitmap
You can check available memory and bitmap details (if needed) as a pre-check
Check the amount of free memory left
public static final float BYTES_IN_MB = 1024.0f * 1024.0f;
public static float megabytesFree() {
final Runtime rt = Runtime.getRuntime();
final float bytesUsed = rt.totalMemory();
final float mbUsed = bytesUsed/BYTES_IN_MB;
final float mbFree = megabytesAvailable() - mbUsed;
return mbFree;
}
public static float megabytesAvailable() {
final Runtime rt = Runtime.getRuntime();
final float bytesAvailable = rt.maxMemory();
return bytesAvailable/BYTES_IN_MB;
}
Check how big is the bitmap we want to load
private void readBitmapInfo() {
final Resources res = getActivity().getResources();
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, R.drawable.brasil, options);
final float imageHeight = options.outHeight;
final float imageWidth = options.outWidth;
final String imageMimeType = options.outMimeType;
Log.d(TAG, "w,h, type:"+imageWidth+", "+imageHeight+", "+imageMimeType);
Log.d(TAG, "estimated memory required in MB: "+imageWidth * imageHeight * BYTES_PER_PX/MemUtils.BYTES_IN_MB);
}
For more details go through Java methods to check memory and bitmap and github discussion
I solved this issue by removing nested scroll view placed above recyclerview. Why OutOfMemory error occurred means, when loading more than 200 images in home page, it is loading all 200 images because of using nested scroll view above recyclerview.
So I can't check the logcat image view width and height one by one in adapter.
After removed nested scroll view fixed out of memory error.because it will load only 3 images displayed in device when coming to home activity.
Also check this, how to use scroll instead of nested scroll view.
.thumbnail(...f)
).skipMemoryCache(true)
if you are not force to keep images in cache.diskCacheStrategy(DiskCacheStrategy.NONE)
to deactivate the disk cacheThis is not an exact solution to your problem, but you need to keep these things in mind while loading images in a list using Glide.
The main threatening part of your problem is the image size. The image you're getting is almost 1mb each! Which is in fact too large for displaying them into a list having 300+ items. So if you're doing the server side too, its always recommended to have the images in several different sizes.
For example, in case of showing a friend list along with their profile pictures, I would suggest you get the whole list first from the server. Then fetch all of the profile images and store them locally. Then populate the ListView
. And the most important part is while uploading a profile picture of an user to the server, after uploading it, the server needs to keep several sizes of it e.g. low, mid and high res version. So that while serving the profile picture urls for the ListView
the server might provide the images with low res as they'll be used most likely for thumbnails.
Using RecyclerView
instead of ListView
is a good call too. But it won't solve the problem you've here when you're in a low-end device.
OMM
has nothing to do with you can solve programatically. You need to resize your image to a lower res version.
You can check for the Glide's caching mechanism too. I would suggest you use the caching strategy so that every time you don't have to load the image from server.
Good luck.
In order to prevent Out of Memory error one can just make precautions to make sure that it will not occurs. So the answer of this question is actually a bunch of suggestions one can suggest. So do I.
As suggested by @Reaz Murshed I am also recommending to have the images in several different sizes. Apart from this I would like to add few more things that might help you analyze this issue and solve it.
As far as I remember OOM was always a usage error, largeHeap
will just delay it; or if it's a large load then maybe it's not possible. So I am suggesting you to follow this link to diagnose for memory leaks.
Stack traces of
OutOfMemoryErrors
don't help at all for diagnosing them. It just tells you it's broken and something filled up the memory. This filling happens much before the actual exception was thrown. This also implies that usually whatever throws theOOM
is not actually the culprit. The only exception to this is when the amount of wannabe allocated memory is simply too big, for example: an array to be allocated is bigger than the maximum memory, then you know that some calculation went really wrong, like a 32000x32000@4 image would take around 4GB of memory.If you can reproduce: get a heap dump and analyze your app's usage. Normal OOM diagnostic steps:
Reproduce exception (wait till you see it in LogCat)
Take a heap dump(To analyze memory leaks)
Analyze it for big objects and leaks
In above shared link there is few another links regarding how to take heap dump?
and issues that are identical with this one.
So I suggest you to analyze for memory leaks and take necessary steps to prevent OOM.
Hope this will help you.