NetworkImageView inside RecyclerView sometimes does not load images when scrolling through the recycleView list quickly. Volley receives slow response from network

advertisements

I have a RecyclerView.

<android.support.v7.widget.RecyclerView android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"/>

I have CardView as a listItem of my RecyclerView

<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
    android:orientation="vertical"
    android:background="@android:color/white"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <com.android.volley.toolbox.NetworkImageView
        android:id="@+id/networkImageView"
        android:adjustViewBounds="true"
        android:scaleType="fitXY"
        android:layout_width="match_parent"
        android:layout_height="130dp"/>
</android.support.v7.widget.CardView>

and in onBindViewHolder of recyclerAdapter I am loading the NetworkImageView with the an image on the network

ImageLoader imageLoader =    RequestUtil.getInstance(_context).getImageLoader();
    String imageUrl = "http://someinterneturl/asdfaas/dsawes.png"; // I get these URL for images from a service.
    networkImageView.setImageUrl(imageUrl,imageLoader);

I have RequestUtil class from where I get my ImageLoader

public class RequestUtil {

private static RequestUtil _instance;
private RequestQueue _requestQueue;
private static Context _ctx;
private ImageLoader _ImageLoader;
private static final String DEFAULT_CACHE_DIR = "volley";
private static final int DEFAULT_NETWORK_THREAD_POOL_SIZE = 8;

private RequestUtil(Context context) {
    _ctx = context;
}

public static synchronized RequestUtil getInstance(Context context) {
    if(_instance == null) {
        _instance = new RequestUtil(context);
    }

    return _instance;
}

public RequestQueue getRequestQueue() {
    if(_requestQueue == null) {
        //_requestQueue = Volley.newRequestQueue(_ctx.getApplicationContext());
        _requestQueue = getNewRequestQueue();
    }

    return _requestQueue;
}

public <T> void addToRequestQueue(Request<T> request) {
    getRequestQueue().add(request);
}

public ImageLoader getImageLoader() {

    if (_ImageLoader == null) {
        _ImageLoader = new ImageLoader(this.getRequestQueue(),
                new LruBitmapCacheUtil());
    }
    return this._ImageLoader;
}

private RequestQueue getNewRequestQueue(){
    Context context = _ctx.getApplicationContext();
    File cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR);
    HttpStack stack= new HurlStack();
    Network network = new BasicNetwork(stack);
    RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network,DEFAULT_NETWORK_THREAD_POOL_SIZE);
    queue.start();
    return queue;

}

}

This works fine but when I scroll the RecyclerViewList fast then sometimes in one NetworkImageView on the screen the image does not load. I see several below logs in android studio

W/art: Long monitor contention with owner Thread-6 (8925) at com.android.volley.Response com.android.volley.toolbox.ImageRequest.parseNetworkResponse(com.android.volley.NetworkResponse)(ImageRequest.java:124) waiters=5 in com.android.volley.Response com.android.volley.toolbox.ImageRequest.parseNetworkResponse(com.android.volley.NetworkResponse) for 279ms

most of the times I also see the below logs even for this images that were displayed.

D/Volley: [416] BasicNetwork.logSlowRequests: HTTP response for request=<[ ] "http://someinterneturl/asdfaas/dsawes.png" 0xe48e98af LOW 249> [lifetime=10978], [size=867672], [rc=200], [retryCount=2]

Please help me in fixing this problem by loading all the images when the scrolling stops and removing the above two warnings from the log. Let me know if you need more information.


You should prefetch the images in the recyclerview, so that when you scroll fast, the images will appear immediately. There are many ways to do it, but none of them is easy. Glide has example on how to prefetch images in recyclerview: https://github.com/bumptech/glide/tree/master/integration/recyclerview