Picasso使用Target无法回调的分析与解决

在加载图片的场景中,有时需要异步拿到Bitmap做一些操作:bitmap预热、bitmap裁剪等,当加载成功的时候通过回调的形式来获取Bitmap,然后进行处理。Picasso提供了一种回调的方式获取Bitmap。客户端实现Target接口即可在加载成功的时候通过回调的方式返回bitmap。代码如下:

Picasso.with(context).load(url).into(new Target() {
  @Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
    //加载成功,进行处理
  }

  @Override public void onBitmapFailed(Drawable errorDrawable) {
    //加载失败
  }

  @Override public void onPrepareLoad(Drawable placeHolderDrawable) {
    //开始加载
  }
});

通过上面的回调函数,我们就可以获取Bitmap,然后进行bitmap的自定义处理。
但是有时候回调却没有触发,也没有异常,最后开启Picasso日志,才发现target引用被gc掉了:
这里写图片描述

一、异步回调的陷阱

后面查看源码之后才发现,由于Picasso将target引用包装成了一个弱引用,当gc发生时target引用就很可能被回收从而无法回调。
首先,先看into(target)源码:

public void into(Target target) {
//代码省略....
//将target作为参数,实例化一个targetAction,此处Action表示picasso的一个抽象行为。
Action action = new TargetAction(picasso, target, request, memoryPolicy, networkPolicy, errorequestKey, tag, errorResId);

}

这里我们可以看到,首先picasso会判断是否从内存中读取,如果不从内存中读取,那么就创建一个新的Action任务,将target作为参数给TargetAction持有。重要关注TargetAction这个类,我们再看一看TargetAction类的构造有什么内容:

final class TargetAction extends Action<Target> {
   

   TargetAction(Picasso picasso, Target target, Request data, int memoryPolicy,Drawable errorDrawable, String key, Object tag, int errorResId) {
      super(picasso, target, data, memoryPolicy, networkPolicy, errorResId, errorDraw,false);
   }
// 代码省略
}

这里可以看到,TargetAction继承了Action类,target引用传给了父类Action的构造函数:

abstract class Action<T> {
   
//picasso实现的弱引用
  static class RequestWeakReference<M> extends WeakReference<M> {
   
    final Acti
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值