垃圾收集和 Picasso 的问题
Issues with garbage collection and Picasso
我正在尝试在 Google Maps Marker 的 InfoWindow 中设置一个 ImageView 并非常准确地从 this answer 复制了代码,除了我的 InfoWindowAdapter 不是匿名内部 class(它只是 activity 的内部 class)。这以前是有效的,但由于某种原因它已停止工作 - 回调中的 onSuccess 方法未被调用,因此 InfoWindow 仅在第二次打开时显示图像。
查看 Picasso 的日志,我收到类似于 Main canceled [R20]+374ms target got garbage collected
的消息。我认为这可能是因为回调正在被 gc 处理,并尝试将其设为最终状态,并将对象保存在 class 字段中(这些都不起作用,尽管也许我做错了?)
这里可能发生了什么,我该如何解决?错误消息中的 target
是指回调,还是指作为参数传递给回调构造函数的标记?
另一件奇怪的事情是,有时首次打开信息窗口时图像会正确加载 - 我试图找出原因,但基本上我有很多标记以及它们的图像是否正确加载第一次去似乎不一致。首次打开信息窗口时,有些(大多数)似乎永远无法正确加载。
[edit] 这是在将一堆代码合并到 activity 之后,所以它会不会是记忆的东西? (现在完成的处理比我没有这个问题的时候多)
[edit 2] 我遇到了与 Glide 完全相同的问题!!可能是垃圾回收?
我不熟悉那个答案,但是 Target
如果您没有强烈引用它,可能会被 gc。
这是因为 Picasso 持有 Target
个引用较弱的实例。
你应该在 Picasso 之外的某个地方持有 Target
实例。
已解决,垃圾回收消息实际上是在引用 ImageView,而不是 Callback 对象。确保 ImageView 对象未被垃圾收集将更正此问题(例如,通过将 ImageView 保存在 class 的字段中,甚至是我的 class 嵌套的 activity 中)
我犯了同样的错误,这是有效的解决方案:
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);
我正在尝试在 Google Maps Marker 的 InfoWindow 中设置一个 ImageView 并非常准确地从 this answer 复制了代码,除了我的 InfoWindowAdapter 不是匿名内部 class(它只是 activity 的内部 class)。这以前是有效的,但由于某种原因它已停止工作 - 回调中的 onSuccess 方法未被调用,因此 InfoWindow 仅在第二次打开时显示图像。
查看 Picasso 的日志,我收到类似于 Main canceled [R20]+374ms target got garbage collected
的消息。我认为这可能是因为回调正在被 gc 处理,并尝试将其设为最终状态,并将对象保存在 class 字段中(这些都不起作用,尽管也许我做错了?)
这里可能发生了什么,我该如何解决?错误消息中的 target
是指回调,还是指作为参数传递给回调构造函数的标记?
另一件奇怪的事情是,有时首次打开信息窗口时图像会正确加载 - 我试图找出原因,但基本上我有很多标记以及它们的图像是否正确加载第一次去似乎不一致。首次打开信息窗口时,有些(大多数)似乎永远无法正确加载。
[edit] 这是在将一堆代码合并到 activity 之后,所以它会不会是记忆的东西? (现在完成的处理比我没有这个问题的时候多)
[edit 2] 我遇到了与 Glide 完全相同的问题!!可能是垃圾回收?
我不熟悉那个答案,但是 Target
如果您没有强烈引用它,可能会被 gc。
这是因为 Picasso 持有 Target
个引用较弱的实例。
你应该在 Picasso 之外的某个地方持有 Target
实例。
已解决,垃圾回收消息实际上是在引用 ImageView,而不是 Callback 对象。确保 ImageView 对象未被垃圾收集将更正此问题(例如,通过将 ImageView 保存在 class 的字段中,甚至是我的 class 嵌套的 activity 中)
我犯了同样的错误,这是有效的解决方案:
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);