我有一个RecyclerView。
<android.support.v7.widget.RecyclerView android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
我将CardView作为我的RecyclerView的listItem
<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>
在recyclerAdapter的onBindViewHolder中我正在使用网络上的图像加载NetworkImageView
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);
我有我的ImageLoader
的RequestUtil类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;
}
}
这样可以正常工作但是当我快速滚动RecyclerViewList
然后有时在屏幕上的一个NetworkImageView
中滚动时图像不会加载。我在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
大多数时候,即使是显示的图像,我也会看到以下日志。
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]
请通过在滚动停止时加载所有图像并从日志中删除上述两个警告来帮助我解决此问题。如果您需要更多信息,请与我们联系。
答案 0 :(得分:1)
不要使用NetworkImageView。 NetworkImageView是一个很好的快捷方式,但它不灵活。通过自己加载,您可以通过ImageRequest或ImageLoader控制图像的加载。例如,如果您检测到回收器视图正在快速滚动,则可以停止发出请求,直到停止为止。但NetworkImageView是为最简单的情况编写的 - 它假设您真的想要图像并立即加载它而不取消。将它用于您不回收的地方。
答案 1 :(得分:0)
您应该在recyclerview中预取图像,这样当您快速滚动时,图像会立即显示。有很多方法可以做到,但这些方法都不容易。 Glide有关于如何在recyclerview中预取图像的示例:https://github.com/bumptech/glide/tree/master/integration/recyclerview
答案 2 :(得分:0)
我在之前的项目中遇到了同样的问题,用Picasso取代了凌空图书馆。
它就像一个魅力,它具有出色的映射下载图像到相应的视图和优化的缓存技术。
请参阅http://square.github.io/picasso/了解使用情况并完成教程。
希望它有所帮助。