当前位置: 动力学知识库 > 问答 > 编程问答 >

Picasso library for Android behaves inconsistently when called repeatedly for ImageView

问题描述:

I am using the Picasso image loading library for Android in my project. I noticed this bug when I saw it loading the wrong image into an ImageView in an ArrayAdapter that utilizes the ViewHolder pattern.

Here is the crux of the bug, which I can now repro consistently in a test Activity I created. I call this method in onCreate:

private void refreshImageView() {

ImageView imageView = (ImageView)this.findViewById(R.id.image);

for (int i = 0; i < 10; i++) {

new Picasso.Builder(this).build()

.load(Uri.parse("http://192.168.1.1:4568/images/red.png"))

.placeholder(R.drawable.silhouette)

.noFade()

.into(imageView);

}

new Picasso.Builder(this).build()

.load(Uri.parse("http://192.168.1.1:4568/images/blue.png"))

.placeholder(R.drawable.silhouette)

.noFade()

.into(imageView);

}

I moreover added some debug output to ImageViewAction.java. Here is what I added:

String str = bitmapToString(result);

Log.i("PicassoDebug", String.format("Complete and loading %s into %s", str.substring(str.length() - 20, str.length() - 1), target));

And here is the output:

12-10 17:08:37.061: I/PicassoDebug(16411): Complete and loading nbAAAAAElF

12-10 17:08:37.061: I/PicassoDebug(16411): TkSuQmCC into android.widget.ImageView{42067f38 V.ED.... ........ 333,482-466,615 #7f08003b app:id/image}

12-10 17:08:37.121: I/PicassoDebug(16411): Complete and loading nbAAAAAElF

12-10 17:08:37.121: I/PicassoDebug(16411): TkSuQmCC into android.widget.ImageView{42067f38 V.ED.... ......ID 333,482-466,615 #7f08003b app:id/image}

12-10 17:08:37.171: I/PicassoDebug(16411): Complete and loading nbAAAAAElF

12-10 17:08:37.171: I/PicassoDebug(16411): TkSuQmCC into android.widget.ImageView{42067f38 V.ED.... ......ID 333,482-466,615 #7f08003b app:id/image}

12-10 17:08:37.221: I/PicassoDebug(16411): Complete and loading nbAAAAAElF

12-10 17:08:37.221: I/PicassoDebug(16411): TkSuQmCC into android.widget.ImageView{42067f38 V.ED.... ......ID 333,482-466,615 #7f08003b app:id/image}

12-10 17:08:37.281: D/dalvikvm(16411): GC_FOR_ALLOC freed 1766K, 22% free 16413K/20988K, paused 32ms, total 33ms

12-10 17:08:37.281: I/PicassoDebug(16411): Complete and loading ewAAAAASUVORK5CYII= into android.widget.ImageView{42067f38 V.ED.... ......ID 333,482-466,615 #7f08003b app:id/image}

12-10 17:08:37.341: I/PicassoDebug(16411): Complete and loading nbAAAAAElF

12-10 17:08:37.341: I/PicassoDebug(16411): TkSuQmCC into android.widget.ImageView{42067f38 V.ED.... ........ 333,482-466,615 #7f08003b app:id/image}

12-10 17:08:37.391: I/PicassoDebug(16411): Complete and loading nbAAAAAElF

12-10 17:08:37.391: I/PicassoDebug(16411): TkSuQmCC into android.widget.ImageView{42067f38 V.ED.... ......ID 333,482-466,615 #7f08003b app:id/image}

12-10 17:08:37.441: I/PicassoDebug(16411): Complete and loading nbAAAAAElF

12-10 17:08:37.441: I/PicassoDebug(16411): TkSuQmCC into android.widget.ImageView{42067f38 V.ED.... ......ID 333,482-466,615 #7f08003b app:id/image}

12-10 17:08:37.501: I/PicassoDebug(16411): Complete and loading nbAAAAAElF

12-10 17:08:37.501: I/PicassoDebug(16411): TkSuQmCC into android.widget.ImageView{42067f38 V.ED.... ......ID 333,482-466,615 #7f08003b app:id/image}

12-10 17:08:37.551: I/PicassoDebug(16411): Complete and loading nbAAAAAElF

12-10 17:08:37.551: I/PicassoDebug(16411): TkSuQmCC into android.widget.ImageView{42067f38 V.ED.... ........ 333,482-466,615 #7f08003b app:id/image}

12-10 17:08:37.601: I/PicassoDebug(16411): Complete and loading nbAAAAAElF

12-10 17:08:37.601: I/PicassoDebug(16411): TkSuQmCC into android.widget.ImageView{42067f38 V.ED.... ......ID 333,482-466,615 #7f08003b app:id/image}

The line that starts with "nbAA" is red.png, the line that starts with "ewAA" is blue.png. As you can see, some of the load requests for red completed after blue, and so red was shown instead of blue.

Is there a bug in picasso? Or is this "by design"? If it is by design, what is the proposed design pattern for using Picasso in ArrayAdapters, which frequently will call getView() repeatedly on the same item before updating?

网友答案:

Figured it out:

When I called new Picasso.Builder(this).build(), I was creating a new object with a new targetToAction hashmap that didn't include the previous requests.

The correct approach to solving this problem is as follows:

private void refreshImageView() {
    ImageView imageView = (ImageView)this.findViewById(R.id.image);

    Picasso p = new Picasso.Builder(this).build();
    for (int i = 0; i < 10; i++) {
        p.load(Uri.parse("http://192.168.1.1:4568/images/red.png"))
        .placeholder(R.drawable.silhouette)
        .noFade()
        .into(imageView);
    }

    p.load(Uri.parse("http://192.168.1.1:4568/images/blue.png"))
    .placeholder(R.drawable.silhouette)
    .noFade()
    .into(imageView);
}

My mistake was in thinking of Picasso as a global singleton. It is not.

分享给朋友:
您可能感兴趣的文章:
随机阅读: