Picasso: Out Of Memory
Solution 1:
I'm not sure fit()
works with android:adjustViewBounds="true"
. According to some of the past issues it seems to be problematic.
A few recommendations:
- Set a fixed size for the ImageView
- User a GlobalLayoutListener to get the ImageView's size once it is calculated and after this call Picasso adding the
resize()
method - Give Glide a try - its default configuration results in a lower footprint than Picasso (it stores the resized imaged rather than the original and uses RGB565)
Solution 2:
.memoryCache(newLruCache(100000000)) // Maybe something fishy here?
I would say this is indeed fishy - you're giving the LruCache
100MB of space. Although all devices are different, this is going to be at or above the limit for some devices, and keep in mind that this is only the LruCache
, not accounting for however much heap space the rest of your app requires. My guess is that this is the direct cause of the exception - you're telling the LruCache
that it's allowed to get much bigger than it should be.
I would reduce this to something like 5MB to first prove the theory, and then experiment with incrementally higher values on your target devices. You can also query the device for how much space it has and set this value programmatically if you like. Finally, there's the android:largeHeap="true"
attribute you can add to your manifest, but I've gathered this is generally bad practice.
Your images are indeed large so I would suggest reducing those as well. Keep in mind that even though you're trimming them, they still temporarily need to be loaded into memory at their full size.
Solution 3:
with picasso you can solve the problem using its property like:
Picasso.with(context)
.load(url)
.resize(300,300)
.into(listHolder.imageview);
you need to resize the image.
Solution 4:
I just made a Singleton class to LoadImages. The problem was that I was using too many Picasso objects created with too many Picasso.Builder. Here's my implementation:
publicclassImagesLoader {
privatestaticImagesLoadercurrentInstance=null;
privatestaticPicassocurrentPicassoInstance=null;
protectedImagesLoader(Context context) {
initPicassoInstance(context);
}
privatevoidinitPicassoInstance(Context context) {
Picasso.Builderbuilder=newPicasso.Builder(context);
builder.listener(newPicasso.Listener() {
@OverridepublicvoidonImageLoadFailed(Picasso picasso, Uri uri, Exception exception) {
exception.printStackTrace();
}
});
currentPicassoInstance = builder.build();
}
publicstatic ImagesLoader getInstance(Context context) {
if (currentInstance == null) {
currentInstance = newImagesLoader(context);
}
return currentInstance;
}
publicvoidloadImage(ImageToLoad loadingInfo) {
StringimageUrl= loadingInfo.getUrl().trim();
ImageViewdestination= loadingInfo.getDestination();
if (imageUrl.isEmpty()) {
destination.setImageResource(loadingInfo.getErrorPlaceholderResourceId());
} else {
currentPicassoInstance
.load(imageUrl)
.placeholder(loadingInfo.getPlaceholderResourceId())
.error(loadingInfo.getErrorPlaceholderResourceId())
.into(destination);
}
}
}
Then you create an ImageToLoad
class that holds the ImageView, Url, Placeholder and Error Placeholder.
publicclassImageToLoad{
privateString url;
private ImageView destination;
privateint placeholderResourceId;
privateint errorPlaceholderResourceId;
//Getters and Setters
}
Post a Comment for "Picasso: Out Of Memory"