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.
I faced the same issue in my previous project and replaced the volley library with Picasso.
It worked like a charm and it have excellent mapping downloaded images to corresponding views and also optimised caching technique.
Refer http://square.github.io/picasso/ for usage and complete tutorial.
Hope it helps.