Search code examples
androidpicasso

Picasso not loading image from a URL, sometimes


My XML code

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
<ImageView
    android:id="@+id/ip_userpic"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@color/whiteColor"
    android:src="@drawable/buddy_menu_icon" />
<TextView
    android:id="@+id/ip_name"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="10dp"
    android:text="@string/ip_name_placeholder" />
<Button
    android:id="@+id/ip_follow"
    style="@style/Widget.AppCompat.Button.Borderless.Colored"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@color/colorBackground"
    android:contentDescription="@string/ip_follow_button"
    android:text="@string/ip_follow_button" />
</LinearLayout>

This XML loads a single row item in a recyclerview. The code for recyclerView.Adapter is below:

@Override
public void onBindViewHolder(final BuddyView fellowBuddy, int position) {
    ---------------- * other code * -----       
Uri uriBuddy = Uri.parse(buddyThis.getPhotoUrl());
Picasso.with(contextFRVA).setLoggingEnabled(true);//Todo: Debug profile photo random behaviour
Picasso.with(contextFRVA).load(uriBuddy).into(fellowBuddy.userPhoto);
    ---------------- * other code * -----
        }

The code for my BuddyView class is as per follows:

class BuddyView extends RecyclerView.ViewHolder {

    CircleImage userPhoto;
    TextView userName;
    String userID;
    Button buttonFollow;

    BuddyView (View itemView) {
        super(itemView);
        this.userPhoto = itemView.findViewById(R.id.ip_userpic);
        this.userName = itemView.findViewById(R.id.ip_name);
        this.buttonFollow = itemView.findViewById(R.id.ip_follow);
    }
}

Now, since I have turned on logging for Picasso, it is logging the below statements:

    11-08 17:08:17.220 8701-8701/me.buddy.buddy D/Picasso: Main        created      [R1] Request{https://lh3.googleusercontent.com/-cNRNYVLKaPE/AAAAAAAAAAI/AAAAAAAAFLM/5KchSe2cA7Y/s96-c/photo.jpg}
11-08 17:08:17.220 8701-8962/me.buddy.buddy D/Picasso: Dispatcher  enqueued     [R1]+4ms 
11-08 17:08:17.230 8701-9237/me.buddy.buddy D/Picasso: Hunter      executing    [R1]+5ms 
11-08 17:08:17.240 8701-8701/me.buddy.buddy D/Picasso: Main        created      [R2] Request{https://lh3.googleusercontent.com/-cNRNYVLKaPE/AAAAAAAAAAI/AAAAAAAAFLM/5KchSe2cA7Y/s96-c/photo.jpg}
11-08 17:08:17.240 8701-8962/me.buddy.buddy D/Picasso: Hunter      joined       [R2]+1ms to [R1]+19ms, [R2]+1ms
11-08 17:08:17.240 8701-9237/me.buddy.buddy D/Picasso: Hunter      decoded      [R1]+20ms 
11-08 17:08:17.240 8701-8962/me.buddy.buddy D/Picasso: Dispatcher  batched      [R1]+21ms, [R2]+4ms for completion
11-08 17:08:17.440 8701-8962/me.buddy.buddy D/Picasso: Dispatcher  delivered    [R1]+222ms, [R2]+205ms 
11-08 17:08:17.460 8701-8701/me.buddy.buddy D/Picasso: Main        completed    [R1]+239ms from DISK
11-08 17:08:17.460 8701-8701/me.buddy.buddy D/Picasso: Main        completed    [R2]+223ms from DISK

All seems to be in order and yet the photo is not loading into the imageview, not at first instance. but if I navigate away from the activity and come back or if the screen goes off and them comes back on, the image is in its proper place. So it seems that any time the activity is getting resumed, the photo is showing. But it is not loading in the first instance itself.

I have tried changing the "wrap_content" of imageview to fixed width and yet same behaviour.

I am not able to figure out exactly what is going wrong. What alternatives can I try?


Solution

  • I finally found the answer to this. I have started using fetch to preload most of the important images in the background of the app. This ensures that I am not running into situations where the activity has been loaded but Picasso is still loading images and displaying placeholder images for a few seconds (or sometimes for eternity). Typical example is

    Picasso.with(getBaseContext()).load(tempUser.getPhotoUrl()).fetch();
    

    Given Picasso's excellent caching and image loading abilities, using fetch to preload some of this notorious images makes for an excellent user experience.