Android 使用毕加索获得带有位图的回调

Android 使用毕加索获得带有位图的回调,android,bitmap,picasso,Android,Bitmap,Picasso,我正在使用下载我的应用程序的图像 我的情况是,在将位图加载到ImageView之前,我需要先访问它。Downloader.Response类的出现似乎表明这是可能的,但我找不到任何使用示例。我不想再写一堆代码来异步处理这一特殊情况,如果可以使用毕加索的话 有人能告诉我怎么做吗 在github上找到答案,以防有人怀疑: private Target target = new Target() { @Override public void onBitmapLoaded(Bi

我正在使用下载我的应用程序的图像

我的情况是,在将位图加载到
ImageView
之前,我需要先访问它。
Downloader.Response
类的出现似乎表明这是可能的,但我找不到任何使用示例。我不想再写一堆代码来异步处理这一特殊情况,如果可以使用毕加索的话


有人能告诉我怎么做吗

在github上找到答案,以防有人怀疑:

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();
}
帖子建议不要使用匿名回调,而是为目标使用实例变量。

摘自:

更新(2016年5月4日):

更新(2016年11月22日)

或者对
目标使用强引用
,这样它就不会被垃圾收集

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);
}
科特林

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?) {

                  }
                }

我想也许你们中的一些人会想要上述答案的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);
        }
    });
}
公共静态可观察加载位图(毕加索-毕加索,字符串图像URL){
返回Observable.create(newobservable.OnSubscribe(){
@凌驾

公共无效呼叫(用户什么比下一个更容易:

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)
    }
}

我使用了毕加索v.2.5.2

版本,理想情况下,您可以直接在视图或视图持有者对象上实现
Target
。如果不这样做,您需要在某个地方保持对实例的强引用,否则它会被垃圾收集。@JakeWharton:如果我想在
列表视图的每个项目上应用自定义动画,您建议执行类似以下操作:
private static ViewHolder{private ImageView ImageView;private Target Target=new Target(){public void onbitmapload(){//do animation ImageView}}
?@JakeWharton在最后一条评论中解释了这一点。onBitmapLoaded在OnPrepareLoad之后不会在第一时间调用。感谢您的示例。我只缺少onDestroy中的超级调用。匿名目标可能是垃圾collected@SteveM那会怎么样?取消请求?阻止加载位图?@nurettin我猜是毕加索(或滑翔)对目标具有某种弱引用。因此,如果它是匿名的,则没有硬引用,并且易受GC攻击。当毕加索检查引用时,它将为null,因此不会调用回调。因此,此解决方案非常糟糕,因为GC可能偶尔会在加载和调用回调之间运行,并导致回调无效被调用。@SteveM我在google play上托管了一个应用程序,它在滚动列表视图的过程中加载了一堆图标,在任何情况下都至少有2000个用户,使用这种方法缩放了一些图标,但我没有看到任何抱怨、评论(我收到很多)或者关于图标未加载的崩溃报告。因此,至少从轶事上说,出于某种原因,它没有被垃圾收集。这段代码现在似乎不能与最新的RxAndroid一起使用
val url: String = "https://...."
val bitmap: Bitmap = Picasso.with(context).load(url).get()
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)