20

Can I download images with Picasso before displaying them? I want to cache images first.

Sample scenario: User clicks on the button, sees the progressbar, and when the images have finished loading user see the images on the screen.

I tried to load images with the "get" method but that did not cache the images.

Thread thread = new Thread()
{
    @Override
    public void run() {
        try {
            Picasso picasso = PicassoOwnCache.with(getApplicationContext());
            RequestCreator picassoRequest;
            for (String imgUrl : imagesUrls) {
                picassoRequest = picasso.load(imgUrl);
                picassoRequest.get();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
};

thread.start();

This is my Picasso singleton class

public class PicassoOwnCache {
    static Picasso singleton = null;
    static Cache cache = null;

    public static Picasso with(int cacheSize, Context context) {
        if (singleton == null) {
            int maxSize = calculateMemoryCacheSize(context);
            cache = new LruCache(cacheSize <= maxSize ? cacheSize : maxSize);
            singleton = new Picasso.Builder(context)
                    .memoryCache(cache)
                    .build();
        }
        return singleton;
    }

    public static Picasso with(Context context) {
        if (singleton == null) {
            cache = new LruCache(calculateMemoryCacheSize(context));
            singleton = new Picasso.Builder(context)
                    .memoryCache(cache)
                    .build();
        }
        return singleton;
    }

    static int calculateMemoryCacheSize(Context context) {
        ActivityManager am = (ActivityManager) context.getSystemService(ACTIVITY_SERVICE);
        boolean largeHeap = (context.getApplicationInfo().flags & FLAG_LARGE_HEAP) != 0;
        int memoryClass = am.getMemoryClass();
        if (largeHeap && Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            memoryClass = ActivityManagerHoneycomb.getLargeMemoryClass(am);
        }
        return 1024 * 1024 * memoryClass / 10;//7;
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    private static class ActivityManagerHoneycomb {
        static int getLargeMemoryClass(ActivityManager activityManager) {
            return activityManager.getLargeMemoryClass();
        }
    }
}

Next show (cached) image to the user.

Picasso picasso = PicassoOwnCache.with(getApplicationContext());
picasso.setDebugging(true) ;
RequestCreator picassoRequest;
picassoRequest = picasso.load(imgUrl);
picassoRequest
        .placeholder(R.drawable.loading_logo)
        .error(R.drawable.no_internet)
        .fit() // I tries also without fit()
        .into(holder.getImageView());

Unfortunately, this does not work. Thanks for yopur suggestions!

Michael Alan Huff
  • 3,462
  • 3
  • 28
  • 44
user3032346
  • 301
  • 1
  • 3
  • 3
  • 44
    Why dont you use `fetch()` instead? – dnkoutso Mar 27 '14 at 03:56
  • @dnkoutso fetch method is returning nothing, then how i will get the bitmap? – AndroidDev Apr 02 '14 at 08:55
  • 14
    I do not see you are doing anything with the returned bitmap in your `get()` call. I highly recommend you use `fetch()` here and let Picasso handle threading and request merging for you. If a fetch is in progress and an `into()` comes it will merge the two and deliver them. – dnkoutso Apr 18 '14 at 15:55
  • 2
    user3032346 .. are you totally aware that **Picasso completely handles caching for you, totally automatically? that is the main purpose of Picasso**. it's a little unclear what you are asking. As far as I can see your entire, total, code base there is **absolutely, totally unnecessary**. Just use one line of Picasso code to load images. – Fattie Jun 06 '14 at 07:51
  • 1
    Resolved! fetch() works fine ... fnx! – user3032346 Aug 24 '16 at 11:37
  • @dnkoutso stop trying to make fetch() happen – Eric Jan 26 '17 at 20:31

2 Answers2

41

As dnkoutso says you just use:

fetch()

Which is built in to Picasso! Please upvote dnkoutso's comment.


PS I'm assuming what you're asking is "how do I make Picasso PRE-LOAD images?"

Note that Picasso absolutely and totally completely handles all caching of images -- with no further effort from you -- that is the purpose of Picasso and why you use it -- that is the raison d'être of Picasso. So you don't need to worry about that.

Again if you're talking pre-loading or let's say "warm-up", then do exactly what dnkoutso said.

(By the way, all of this simply comes down to: "how good things look in long ListViews of images". We've actually found that Picasso is just so smooth, you really don't even need to worry, generally, about a warm-up phase in most apps. indeed, even critical concepts like this....

http://lucasr.org/2012/04/05/performance-tips-for-androids-listview/

Note - this famous article http://www.programmingmobile.com/2012/03/buttery-smooth-list-scrolling-in.html has disappeared from the web ..

... really Picasso is just so easy to use, you, really, rarely need to bother with "old-fashioned" carefully ListView handling. In short you very rarely need to worry about "warm-up", we've found. Hope it helps.)

Community
  • 1
  • 1
Fattie
  • 27,874
  • 70
  • 431
  • 719
9

You can fetch images before displaying. After it is loaded, you can load into imageView. When you call Picasso#load() second time, image won't be downloaded again. It will come from cache.

startProgress(); // handle showing progress view somehow
Picasso.with(getActivity()).load(imageUrl).fetch(new Callback() {
    @Override
    public void onSuccess() {
        Picasso.with(getActivity()).load(imageUrl).into(imgViewMedia);
        stopProgress(); // handle stopping progress view somehow
    }

    @Override
    public void onError() {

    }
});
sembozdemir
  • 4,137
  • 3
  • 21
  • 30