Use Picasso to get a callback with a Bitmap - android

I'm using Picasso to download images for my app.
I'm in a situation where I need to access the Bitmap first before it's loaded into the ImageView. The presence of the Downloader.Response class seems to suggest this is possible, but I can't find any use examples. I don't want to write a bunch more code to asynchronously handle this one particular case if it's possible to do with Picasso.
Can anyone show me how to do it?

Found the answer on github in case anyone is wondering:
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();
}
The post recommends not using an anonymous callback, and instead using an instance variable for target.

taken from here:
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);
}
});
Updated (May 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) {
}
});
Updated (November 22, 2016)
or using a strong reference for Target so that it wont be garbage collected
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?) {
}
}

What can be easy than next:
val url: String = "https://...."
val bitmap: Bitmap = Picasso.with(context).load(url).get()
Should be called from not the main thread!
or with 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)
}
}
Retrieve Bitmap:
getBitmapSingle(Picasso.with(context), "https:/...")
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ bitmap ->
// val drawable = BitmapDrawable(context, bitmap)
}, Throwable::printStackTrace)
I used Picasso v.2.5.2

I thought maybe some of you would like an RxJava version of the above answer... Here it is:
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);
}
});
}
P.S. When subscribing, store the subscription reference on your activity, otherwise, target will be GC'd before you receive a response...

Related

Android Picasso load into Target sometimes not working

I have this code to load some images in the adapter. The problem is that most of time it works but sometimes the list was not displayed.
for (Product p: listItem) {
Picasso.get().load( p.getBanner()).into(new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
bitmapList.add(bitmap);
notifyDataSetChanged();
}
#Override
public void onBitmapFailed(Exception e, Drawable errorDrawable) {
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
});
}
The problem was because I have used anonymous Target made the object eligible for garbage collection and sometimes it destroyed by Garbage Collector.

Unable to load bitmap using Glide v4

I am using Glide v4 to load a bitmap that can then be used to as a marker on the map. When I use the deprecated SimpleTarget like so everything works fine.
GlideApp.with(getContext()).asBitmap().load(url)
.into(new SimpleTarget<Bitmap>() {
#Override
public void onResourceReady(#NonNull Bitmap resource, #Nullable Transition<? super Bitmap> transition) {
// load bitmap as marker
}
});
When I try removing the deprecated code and using Target<Bitmap> like given below I can see the onLoadStarted gets called but the onResourceReady is never called neither is the onLoadFailed.
GlideApp.with(getContext()).asBitmap()
.load(UrlHelper.createUrl(poi.getMapMarker()))
.into(marketBitmap);
private Target<Bitmap> marketBitmap = new Target<Bitmap>() {
#Override
public void onLoadStarted(#Nullable Drawable placeholder) {
Log.d("GlideMar", "marker load started");
}
#Override
public void onLoadFailed(#Nullable Drawable errorDrawable) {
Log.e("GlideMar", "marker load failed");
}
#Override
public void onResourceReady(#NonNull Bitmap resource, #Nullable Transition<? super Bitmap> transition) {
Log.d("GlideMar", "onResourceReady");
}
#Override
public void onLoadCleared(#Nullable Drawable placeholder) {
Log.d("GlideMar", "marker onLoadCleared");
}
#Override
public void getSize(#NonNull SizeReadyCallback cb) {
}
#Override
public void removeCallback(#NonNull SizeReadyCallback cb) {
}
#Override
public void setRequest(#Nullable Request request) {
}
#Nullable
#Override
public Request getRequest() {
return null;
}
#Override
public void onStart() {
Log.d("GlideMar", "marker onStart");
}
#Override
public void onStop() {
Log.d("GlideMar", "marker onStop");
}
#Override
public void onDestroy() {
Log.d("GlideMar", "marker onDestroy");
}
};
From Glide Custom Targets documentation.
If you’re using a custom Target and you’re not loading into a View
that would allow you to subclass ViewTarget, you’ll need to implement
the getSize() method.
So in your case just put the below code in getSize method
#Override
public void getSize(SizeReadyCallback cb) {
cb.onSizeReady(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL);
}
Now the onResourceReady method will be called when you run the app.

Holding strong reference to Picasso Target does not work

I am using Picasso to add an icon to my actionbar. I've read that in order to load the image every time I need to make my Target of strong reference and for that I've used final. But, again, it goes into onPrepareLoad and never reaches onBitmapLoaded.
What am I doing wrong?
private void setLogoToActionBar() {
final Target target = new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
Log.d("DEBUG", "onBitmapLoaded");
Drawable d = new BitmapDrawable(getResources(), bitmap);
actionBar.setIcon(d);
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
Log.d("DEBUG", "onBitmapFailed");
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
Log.d("DEBUG", "onPrepareLoad");
actionBar.setIcon(placeHolderDrawable);
}
};
Picasso.with(getContext()).load(mShop.getClientLogo()).placeholder(R.drawable.shop_asset).resize(100, 100).into(target);
}

Picasso never calling completion handler while trying to load an image on Android

I am trying to load an image:
Picasso.with(SelectActivity.this).load(picture).into(new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
bmp = bitmap;
findViewById(R.id.facebookButton).setEnabled(true);
continueToEditing();
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
findViewById(R.id.facebookButton).setEnabled(true);
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
});
picture is a valid string to a reachable, valid JPEG image. I've got everything inside a try/catch block and I've got breakpoints on onBitmapLoaded, onBitmapFailed, and try/catch's catch block.
However, none of this is called. There is also nothing in logcat related to this, too. What am I doing wrong?
Try keeping a strong reference to the Target object as a class variable and give it a try.
E.g.
Target target;// Class variable
//Now define this on your onCreate method
target = new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
bmp = bitmap;
findViewById(R.id.facebookButton).setEnabled(true);
continueToEditing();
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
findViewById(R.id.facebookButton).setEnabled(true);
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
});
//Now set the target on the Piccaso load LOC
Picasso.with(SelectActivity.this).load(picture).into(target);

Unable to download the bitmap to a target using Picasso?

I am trying to load the bitmaps to an arraylist as follows:
Picasso.with(context).load(url).into(new Target(){
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
//mainLayout.setBackground(new BitmapDrawable(context.getResources(), bitmap));
photos.add(bitmap);
}
#Override
public void onBitmapFailed(final Drawable errorDrawable) {
Log.d("TAG", "FAILED");
}
#Override
public void onPrepareLoad(final Drawable placeHolderDrawable) {
Log.d("TAG", "Prepare Load");
}
});
But why is the onBitmapLoaded method never called?
Picasso, doesn't hold strong references to new Target() it will be garbage collected
look over this

Categories

Resources