3

RecyclerView があります。

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

RecyclerView の listItem として CardView を持っています

<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スタジオで以下のログがいくつか表示されます

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]

スクロールが停止したときにすべての画像を読み込み、上記の 2 つの警告をログから削除して、この問題を解決してください。さらに情報が必要な場合はお知らせください。

4

3 に答える 3

1

以前のプロジェクトで同じ問題に直面し、volley ライブラリを Picasso に置き換えました。

それは魅力のように機能し、ダウンロードされた画像を対応するビューにマッピングし、最適化されたキャッシュ技術も備えています。

使用法と完全なチュートリアルについては、http://square.github.io/picasso/を参照してください。

それが役に立てば幸い。

于 2017-01-08T08:47:57.423 に答える
1

NetworkImageView を使用しないでください。NetworkImageView は便利なショートカットですが、柔軟性に欠けます。自分で読み込みを行うことで、ImageRequest または ImageLoader を介して画像の読み込みを制御できます。たとえば、リサイクラー ビューが急速にスクロールしていることを検出した場合は、停止するまでリクエストの作成を停止できます。ただし、NetworkImageView は最も単純なケース向けに作成されています。実際に画像が必要であると想定し、キャンセルせずにすぐに読み込みます。リサイクルしないものに使用します。

于 2017-01-08T08:57:28.947 に答える
0

recyclerview で画像をプリフェッチして、すばやくスクロールしたときに画像がすぐに表示されるようにする必要があります。それを行うには多くの方法がありますが、どれも簡単ではありません。Glide には、recyclerview で画像をプリフェッチする方法の例があります: https://github.com/bumptech/glide/tree/master/integration/recyclerview

于 2017-01-08T08:08:44.840 に答える