android - मैं पिकासो में डिस्क कैशिंग का उपयोग कैसे करूं?




image caching (5)

मैं अपने एंड्रॉइड ऐप में छवि प्रदर्शित करने के लिए पिकासो का उपयोग कर रहा हूं:

/**
* load image.This is within a activity so this context is activity
*/
public void loadImage (){
    Picasso picasso = Picasso.with(this); 
    picasso.setDebugging(true);
    picasso.load(quiz.getImageUrl()).into(quizImage);
}

मैंने डिबगिंग सक्षम कर दी है और यह हमेशा लाल और हरा दिखाती है लेकिन कभी पीले रंग को नहीं दिखाती है

अब अगर मैं अगली बार एक ही छवि लोड करता हूं और इंटरनेट उपलब्ध नहीं है तो छवि लोड नहीं होती है।

प्रशन:

  1. क्या इसमें स्थानीय डिस्क कैश नहीं है?
  2. मैं डिस्क कैशिंग को कैसे सक्षम करूं क्योंकि मैं एक ही छवि का उपयोग कई बार करूँगा।
  3. क्या मुझे एंड्रॉइड मेनिफेस्ट फ़ाइल में कुछ डिस्क अनुमति जोड़ने की ज़रूरत है?

1) डिफ़ॉल्ट रूप से पिकासो में कैश है (अहमद हामी जवाब देखें)

2) यदि आपको वास्तव में डिस्क कैश से छवि लेनी चाहिए और फिर नेटवर्क मैं अपना खुद का डाउनलोडर लिखने की सलाह देता हूं:

public class OkHttpDownloaderDiskCacheFirst extends OkHttpDownloader {
    public OkHttpDownloaderDiskCacheFirst(OkHttpClient client) {
        super(client);
    }

    @Override
    public Response load(Uri uri, int networkPolicy) throws IOException {
        Response responseDiskCache = null;
        try {
            responseDiskCache = super.load(uri, 1 << 2); //NetworkPolicy.OFFLINE
        } catch (Exception ignored){} // ignore, handle null later

        if (responseDiskCache == null || responseDiskCache.getContentLength()<=0){
            return  super.load(uri, networkPolicy); //user normal policy
        } else {
            return responseDiskCache;
        }

    }
}

और विधि में सिंगलटन में ऑनक्रेट इसे पिकासो के साथ उपयोग करें:

        OkHttpClient okHttpClient = new OkHttpClient();

        okHttpClient.setCache(new Cache(getCacheDir(), 100 * 1024 * 1024)); //100 MB cache, use Integer.MAX_VALUE if it is too low
        OkHttpDownloader downloader = new OkHttpDownloaderDiskCacheFirst(okHttpClient); 

        Picasso.Builder builder = new Picasso.Builder(this);

        builder.downloader(downloader);

        Picasso built = builder.build();

        Picasso.setSingletonInstance(built);

3) defalut अनुप्रयोग कैश फ़ोल्डर के लिए कोई अनुमति की आवश्यकता नहीं है


Application.onCreate में followning कोड जोड़ें तो इसे सामान्य का उपयोग करें

    Picasso picasso = new Picasso.Builder(context)
            .downloader(new OkHttp3Downloader(this,Integer.MAX_VALUE))
            .build();
    picasso.setIndicatorsEnabled(true);
    picasso.setLoggingEnabled(true);
    Picasso.setSingletonInstance(picasso);

यदि आप पहले छवियों को कैश करते हैं तो ProductImageDownloader.doBackground में ऐसा कुछ करें

final Callback callback = new Callback() {
            @Override
            public void onSuccess() {
                downLatch.countDown();
                updateProgress();
            }

            @Override
            public void onError() {
                errorCount++;
                downLatch.countDown();
                updateProgress();
            }
        };
        Picasso.with(context).load(Constants.imagesUrl+productModel.getGalleryImage())
                .memoryPolicy(MemoryPolicy.NO_CACHE).fetch(callback);
        Picasso.with(context).load(Constants.imagesUrl+productModel.getLeftImage())
                .memoryPolicy(MemoryPolicy.NO_CACHE).fetch(callback);
        Picasso.with(context).load(Constants.imagesUrl+productModel.getRightImage())
                .memoryPolicy(MemoryPolicy.NO_CACHE).fetch(callback);

        try {
            downLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        if(errorCount == 0){
            products.remove(productModel);
            productModel.isDownloaded = true;
            productsDatasource.updateElseInsert(productModel);
        }else {
            //error occurred while downloading images for this product
            //ignore error for now
            // FIXME: 9/27/2017 handle error
            products.remove(productModel);

        }
        errorCount = 0;
        downLatch = new CountDownLatch(3);

        if(!products.isEmpty() /*&& testCount++ < 30*/){
            startDownloading(products.get(0));
        }else {
            //all products with images are downloaded
            publishProgress(100);
        }

और अपनी छवियों को सामान्य या डिस्क कैशिंग के साथ लोड करें

    Picasso.with(this).load(Constants.imagesUrl+batterProduct.getGalleryImage())
        .networkPolicy(NetworkPolicy.OFFLINE)
        .placeholder(R.drawable.GalleryDefaultImage)
        .error(R.drawable.GalleryDefaultImage)
        .into(viewGallery);

ध्यान दें:

लाल रंग इंगित करता है कि छवि नेटवर्क से प्राप्त की जाती है

हरा रंग इंगित करता है कि छवि कैश मेमोरी से प्राप्त की जाती है।

नीला रंग इंगित करता है कि छवि डिस्क मेमोरी से प्राप्त की जाती है।

ऐप को रिलीज़ करने से पहले या इसे false picasso.setLoggingEnabled(true); सेट करें picasso.setLoggingEnabled(true); , picasso.setIndicatorsEnabled(true); यदि आवश्यक नहीं है। thankx


मुझे एक ही समस्या थी और इसके बजाय ग्लाइड लाइब्रेरी का इस्तेमाल किया गया था। कैश बॉक्स से बाहर है। https://github.com/bumptech/glide


मैं इस कोड का उपयोग करता हूं और काम करता हूं, शायद आपके लिए उपयोगी:

public static void makeImageRequest(final View parentView,final int id, final String imageUrl) {

    final int defaultImageResId = R.mipmap.user;
    final ImageView imageView = (ImageView) parentView.findViewById(id);
    Picasso.with(context)
            .load(imageUrl)
            .networkPolicy(NetworkPolicy.OFFLINE)
            .into(imageView, new Callback() {
                @Override
                public void onSuccess() {
                Log.v("Picasso","fetch image success in first time.");
                }

                @Override
                public void onError() {
                    //Try again online if cache failed
                    Log.v("Picasso","Could not fetch image in first time...");
                    Picasso.with(context).load(imageUrl).networkPolicy(NetworkPolicy.NO_CACHE)
                            .memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE).error(defaultImageResId)
                            .into(imageView, new Callback() {

                                @Override
                                public void onSuccess() {
                                    Log.v("Picasso","fetch image success in try again.");
                                }

                                @Override
                                public void onError() {
                                  Log.v("Picasso","Could not fetch image again...");
                                }

                            });
                }
            });

}

1) पहले प्रश्न का उत्तर: पिकासो डॉक के साथ () विधि के अनुसार

वैश्विक डिफ़ॉल्ट पिकासो उदाहरण () से लौटाया गया है स्वचालित रूप से उन डिफ़ॉल्टों के साथ प्रारंभ किया गया है जो अधिकांश कार्यान्वयन के लिए उपयुक्त हैं।

  • उपलब्ध अनुप्रयोग रैम 15% की एलआरयू मेमोरी कैश
  • 50 एमबी तक 2% स्टोरेज स्पेस का डिस्क कैश लेकिन 5 एमबी से कम नहीं।

लेकिन वैश्विक डिफ़ॉल्ट पिकासो के लिए Disk Cache ऑपरेशन केवल API 14+ पर उपलब्ध है

2) दूसरे प्रश्न का उत्तर: Picasso Disk Cache ऑपरेशन के लिए HTTP क्लाइंट अनुरोध का उपयोग करता है ताकि आप अपने स्वयं के http request header को max-age साथ Cache-Control कर सकें और डिफ़ॉल्ट पिकासो के बजाय अपना स्वयं का स्टेटिक पिकासो इंस्टेंस बना सकें

1] HttpResponseCache (नोट: केवल एपीआई 13+ के लिए काम करता है)
2] OkHttpClient (सभी एपीआई के लिए काम करता है)

अपनी खुद की स्टेटिक पिकासो कक्षा बनाने के लिए OkHttpClient का उपयोग करने के लिए उदाहरण :

  • सबसे पहले अपनी खुद की सिंगलटन picasso ऑब्जेक्ट प्राप्त करने के लिए एक नई कक्षा बनाएं

    import android.content.Context;
    import com.squareup.picasso.Downloader;
    import com.squareup.picasso.OkHttpDownloader;
    import com.squareup.picasso.Picasso;
    
    public class PicassoCache {
    
        /**
         * Static Picasso Instance
         */
        private static Picasso picassoInstance = null;
    
        /**
         * PicassoCache Constructor
         *
         * @param context application Context
         */
        private PicassoCache (Context context) {
    
            Downloader downloader   = new OkHttpDownloader(context, Integer.MAX_VALUE);
            Picasso.Builder builder = new Picasso.Builder(context);
                builder.downloader(downloader);
    
            picassoInstance = builder.build();
        }
    
        /**
         * Get Singleton Picasso Instance
         *
         * @param context application Context
         * @return Picasso instance
         */
        public static Picasso getPicassoInstance (Context context) {
    
            if (picassoInstance == null) {
    
                new PicassoCache(context);
                return picassoInstance;
            }
    
            return picassoInstance;
        }
    
    } 
    
  • picasso बजाय अपने स्वयं के सिंगलटन picasso ऑब्जेक्ट का उपयोग करें। Picasso.With()

PicassoCache.getPicassoInstance(getContext()).load(imagePath).into(imageView)

3) तीसरे प्रश्न के लिए उत्तर: आपको डिस्क कैश संचालन के लिए किसी भी डिस्क अनुमतियों की आवश्यकता नहीं है

संदर्भ : डिस्क कैश के बारे में गिथब मुद्दे , दो प्रश्नों का उत्तर @jake-wharton -> Question1 और Question2





picasso