垃圾回收和Picasso存在的问题

5
我正在尝试在Google Maps Marker的InfoWindow中设置ImageView,并从这个答案中复制了代码,除了我的InfoWindowAdapter不是匿名内部类(它只是活动的内部类)。之前这样可以工作,但出于某些原因它停止工作了——回调中的onSuccess方法没有被调用,因此InfoWindow只在第二次打开时显示图像。
查看Picasso的日志,我得到类似于Main canceled [R20]+374ms target got garbage collected的消息。我想这可能是因为Callback被gc了,尝试将其设为final,并保存在类字段中(但都没起作用,或许我做错了?)。
这里可能发生了什么,我该如何解决?错误信息中的target是指回调吗,还是可能指传递给回调构造函数的标记?
另一个奇怪的事情是,有时当首次打开InfoWindow时,图片会正确加载——我正在尝试找出原因,但基本上我有很多标记,它们的图片在第一次尝试时是否正确加载似乎不一致。有些(大多数)在第一次打开InfoWindow时似乎永远无法正确加载。
[编辑]这是在大量代码合并到那个活动之后,所以可能是内存问题吗?(现在比之前处理的内容更多)
[编辑2]我用Glide遇到了完全相同的问题!可能是垃圾收集?
3个回答

8
我不熟悉那个答案,但是当您不持有对它的强引用时,Target 可能会被垃圾回收。
这是因为 Picasso 使用弱引用持有 Target 实例。
您应该在 Picasso 之外的地方持有 Target 实例。
请查看此问题:https://github.com/square/picasso/issues/352

谢谢,我尝试将Callback对象存储在活动中的字段中(Callback和InfoWindowAdapter都嵌套在其中),然后将该字段作为参数传递给.into(),但我收到相同的消息和问题(不确定我是否正确处理了它)[编辑] 显然,回调始终被保留为强引用。 - false_azure

2

问题已解决,垃圾回收信息实际上是指向ImageView,而不是Callback对象。确保ImageView对象不被垃圾回收将会纠正这个问题(例如通过在类中或甚至是嵌套在我的类中的活动中保存ImageView)。


0

我也犯了同样的错误,这是有效的解决方案:

My previous code :

        picasso.load(url).into(new Target() {
    @Override
    public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {

    }

    @Override
    public void onBitmapFailed(Exception e, Drawable errorDrawable) {

    }

    @Override
    public void onPrepareLoad(Drawable placeHolderDrawable) {

    }
});

After this I just created a new variable for Target object :

final Target target=new Target() {
    @Override
    public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
        imageView.setBackground(new BitmapDrawable(mContext.getResources(), bitmap));
        imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
    }

    @Override
    public void onBitmapFailed(Exception e, Drawable errorDrawable) {

    }

    @Override
    public void onPrepareLoad(Drawable placeHolderDrawable) {

    }
};

then I used the target object later in my code :

        picasso.load(url).into( target);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接