एक बिटमैप के साथ कॉलबैक प्राप्त करने के लिए पिकासो का उपयोग करें


83

मैं अपने ऐप के लिए चित्र डाउनलोड करने के लिए पिकासो का उपयोग कर रहा हूं ।

मैं ऐसी स्थिति में हूं जहां मुझे Bitmapइसमें लोड होने से पहले पहले एक्सेस करना होगा ImageViewDownloader.Responseकक्षा की मौजूदगी से लगता है कि यह संभव है, लेकिन मुझे इसका कोई उदाहरण नहीं मिल रहा है। यदि यह संभव हो तो पिकासो के साथ ऐसा करने के लिए मैं एक विशेष कोड को असंबद्ध रूप से हैंडल करने के लिए एक गुच्छा अधिक कोड लिखना नहीं चाहता।

क्या कोई मुझे दिखा सकता है कि यह कैसे करना है?


जवाबों:


172

गितुब पर जवाब मिला अगर कोई सोच रहा है:

private Target target = new Target() {
      @Override
      public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
      }

      @Override
      public void onBitmapFailed(Drawable errorDrawable) {
      }

      @Override
      public void onPrepareLoad(Drawable placeHolderDrawable) {
      }
}

private void someMethod() {
   Picasso.with(this).load("url").into(target);
}

@Override 
public void onDestroy() {  // could be in onPause or onStop
   Picasso.with(this).cancelRequest(target);
   super.onDestroy();
}

पोस्ट एक गुमनाम कॉलबैक का उपयोग नहीं करने की सलाह देता है, और इसके बजाय लक्ष्य के लिए एक उदाहरण चर का उपयोग कर रहा है।


30
आदर्श रूप से आप Targetसीधे किसी दृश्य या दृश्य धारक ऑब्जेक्ट पर लागू करेंगे । यदि आप ऐसा नहीं कर रहे हैं, तो आपको कहीं न कहीं उदाहरण के लिए एक मजबूत संदर्भ बनाए रखना होगा अन्यथा यह कचरा एकत्र हो जाएगा।
जेक व्हार्टन

@JakeWharton: अगर मैं हर आइटम पर एक कस्टम एनीमेशन लागू करना चाहता हूं ListView, तो आप कुछ ऐसा करने का सुझाव देते हैं private static ViewHolder { private ImageView imageView; private Target target = new Target() { public void onBitmapLoaded() { // do animation on imageView } } }:?
mbmc

@JakeWharton ने पिछली टिप्पणी में इसे github.com/square/picasso/issues/308 यहाँ बताया है ।
टोब्स्को 42

8
onPitpareLoad के बाद पहली बार onBitmapLoaded कॉल नहीं
अमित थापर

उदाहरण के लिए धन्यवाद। मुझे केवल onDestroy में एक सुपर कॉल याद आ रही है।
बेन ग्रोट

68

यहाँ से लिया गया :

Picasso.with(this)
    .load(url)
    .into(new Target() {
        @Override
        public void onBitmapLoaded (final Bitmap bitmap, Picasso.LoadedFrom from){
            /* Save the bitmap or do something with it here */

            //Set it in the ImageView
            theView.setImageBitmap(bitmap); 
        }
});

अपडेट किया गया (04 मई, 2016):

            Picasso.with(this)
                .load(youUrl)
                .into(new Target() {
                    @Override
                    public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {

                    }

                    @Override
                    public void onBitmapFailed(Drawable errorDrawable) {

                    }

                    @Override
                    public void onPrepareLoad(Drawable placeHolderDrawable) {

                    }
                });

अपडेट किया गया (22 नवंबर, 2016)

या इसके लिए एक मजबूत संदर्भ का उपयोग करते हुए, Targetताकि यह कचरा एकत्र न हो

Target target = new Target() {
            @Override
            public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {

            }

            @Override
            public void onBitmapFailed(Drawable errorDrawable) {

            }

            @Override
            public void onPrepareLoad(Drawable placeHolderDrawable) {

            }
        };


void foo() {
        Picasso.with(getContext()).load(getUrl()).into(target);
}

Kotlin

object: com.squareup.picasso.Target {
                  override fun onBitmapFailed(e: java.lang.Exception?, errorDrawable: Drawable?) {
                    TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
                }

                  override fun onPrepareLoad(placeHolderDrawable: Drawable?) {
                    TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
                  }

                  override fun onBitmapLoaded(bitmap: Bitmap?, from: Picasso.LoadedFrom?) {

                  }
                }

6
अनाम लक्ष्य कचरा एकत्र किया जा सकता है
स्टीव एम

@SteveM और वह क्या करेगा? अनुरोध रद्द करें? बिटमैप को लोड होने से रोकें?
nurettin

@nurettin मैं पिकासो (या ग्लाइड) मान रहा हूँ कि लक्ष्य के लिए कमजोर संदर्भ है। इसलिए अगर यह गुमनाम है तो कोई कठिन संदर्भ नहीं है और यह GC के लिए असुरक्षित है। जब पिकासो संदर्भ की जाँच करता है तो यह शून्य हो जाएगा इसलिए कॉलबैक नहीं कहा जाएगा।
स्टीव एम

तो यह समाधान वास्तव में बुरा है क्योंकि जीसी कभी-कभार कॉलबैक के लोडिंग और कॉलिंग के बीच में चल सकता है और कॉलबैक का कारण नहीं कहला सकता है।
स्टीव एम

@SteveM मैंने Google Play पर एक एप्लिकेशन होस्ट किया है जो किसी भी उदाहरण में कम से कम 2000 उपयोगकर्ताओं के साथ अपने सूचियों के स्क्रॉल के दौरान आइकन का एक गुच्छा लोड करता है, इस पद्धति का उपयोग करके कुछ आइकन स्केल करता है, लेकिन मैंने कोई शिकायत नहीं देखी है, टिप्पणी () मैं बहुत सारी प्राप्त करता हूं) या लोड नहीं होने वाले आइकन के बारे में क्रैश रिपोर्ट। तो कम से कम anecdotally, यह कचरा किसी कारण के लिए एकत्र नहीं किया जा रहा है।
nurettin

7

आगे क्या आसान हो सकता है:

val url: String = "https://...."
val bitmap: Bitmap = Picasso.with(context).load(url).get()

मुख्य धागे से नहीं बुलाया जाना चाहिए!

या RxJava 2 के साथ:

fun getBitmapSingle(picasso: Picasso, url: String): Single<Bitmap> = Single.create {
    try {
        if (!it.isDisposed) {
            val bitmap: Bitmap = picasso.load(url).get()
            it.onSuccess(bitmap)
        }
    } catch (e: Throwable) {
        it.onError(e)
    }
}

बिटमैप पुनर्प्राप्त करें:

getBitmapSingle(Picasso.with(context), "https:/...")
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({ bitmap ->
                // val drawable = BitmapDrawable(context, bitmap)
                }, Throwable::printStackTrace)

मैंने पिकासो v.2.5.2 का उपयोग किया


2

मैंने सोचा कि शायद आप में से कुछ उपरोक्त उत्तर के RxJava संस्करण को पसंद करेंगे ... यहाँ यह है:

    public static Observable<Bitmap> loadBitmap(Picasso picasso, String imageUrl) {
    return Observable.create(new Observable.OnSubscribe<Bitmap>() {
        @Override
        public void call(Subscriber<? super Bitmap> subscriber) {
            Target target = new Target() {
                @Override
                public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
                    subscriber.onNext(bitmap);
                    subscriber.onCompleted();
                }

                @Override
                public void onBitmapFailed(Drawable errorDrawable) {
                    subscriber.onError(new Exception("failed to load " + imageUrl));
                }

                @Override
                public void onPrepareLoad(Drawable placeHolderDrawable) {
                }
            };
            subscriber.add(new Subscription() {
                private boolean unSubscribed;

                @Override
                public void unsubscribe() {
                    picasso.cancelRequest(target);
                    unSubscribed = true;
                }

                @Override
                public boolean isUnsubscribed() {
                    return unSubscribed;
                }
            });
            picasso.load(imageUrl).into(target);
        }
    });
}

PS सदस्यता लेते समय, अपनी गतिविधि पर सदस्यता संदर्भ को संग्रहीत करें, अन्यथा, प्रतिक्रिया प्राप्त करने से पहले लक्ष्य GC'd होगा ...


लगता है कि यह कोड अब नवीनतम RxAndroid
Pavandroid
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.