0

アプリケーションに ListView があり、ListView の項目に画像が表示されます。したがって、Http から画像をロードするには、ローダーを非同期にする必要があります。

今、私は Google の Bitmapfun を使用しています。

だから私はそれを書き直して、問題に遭遇したいと思っています。

Http から同じ Url イメージをダウンロードし、両方とも httpRequest と非同期実行を繰り返さない方法は?

ListViewの項目なので、同じ画像を表示している可能性があります。Bitmapfun では、Google はプロセスを「同期」しました,そのため、画像をダウンロードするための同時実行ができませんでした。</p>

助けて!ありがとうございます(T_T)

.........すみません、英語が下手です。

たとえば、ListView には 5 つの項目があります。すべてのアイテムには、画像を表示するための ImageView があります。AsyncTask を使用して Http リクエストを作成し、ダウンロードしてキャッシュに入れ、表示します。

多分5つの画像は

"hxxp://xxx.com/1.jpg",

"Hxxp://xxx.com/2.jpg",

"hxxp://xxx.com/3.jpg",

"hxxp://xxx.com/1.jpg",

「Hxxp://xxx.com/1.jpg」

したがって、3 つの Http 要求は同じです。しかし、AsyncTask は同時に機能します。したがって、他の 2 つの Http 要求は繰り返しでした。

私が解決したい問題は、「AsyncTaskの画像をダウンロードする方法ですが、同じURLが一度しかダウンロードされない場合はどうすればよいですか?」.....

編集:レイジーリストを使用:

 private Bitmap getBitmap(String url) 
{
    File f=fileCache.getFile(url);

    //from SD cache
    Bitmap b = decodeFile(f);
    if(b!=null){
        Log.d("ImageLoader", " From Cache" + url);
        return b;
    }
    //from web
    try {
        Log.d("ImageLoader", " Begin Downloading" + url);
        Bitmap bitmap=null;
        URL imageUrl = new URL(url);
        HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection();
        conn.setConnectTimeout(30000);
        conn.setReadTimeout(30000);
        conn.setInstanceFollowRedirects(true);
        InputStream is=conn.getInputStream();
        OutputStream os = new FileOutputStream(f);
        Utils.CopyStream(is, os);
        os.close();
        conn.disconnect();
        bitmap = decodeFile(f);
        return bitmap;
    } catch (Throwable ex){
       ex.printStackTrace();
       if(ex instanceof OutOfMemoryError)
           memoryCache.clear();
       return null;
    }
}

ListView を初期化すると、ログは次のようになります。

04-09 10:44:31.900: D/ImageLoader(8578): ダウンロード開始:31.910: D/ImageLoader(8578): ダウンロード開始(8578): ダウンロードを開始しますhxxps://lh6.googleusercontent.com/-55osAWw3x0Q/URquUtcFr5I/AAAAAAAAAbs/rWlj1RUKrYI/s1024/A%252520Photographer.jpg 04-09 10:44:31.930: D/ImageLoader(8578): ダウンロード開始 hxxps://lh6.グーグルユーザーコンテンツ。com/-55osAWw3x0Q/URquUtcFr5I/AAAAAAAAAbs/rWlj1RUKrYI/s1024/A%252520Photographer.jpg 04-09 10:44:33.090: I/MemoryCache(8578): キャッシュ サイズ=44032 長さ=1 04-09 10:44:33.090: D/ImageLoader(8578): ダウンロードを開始しますI/MemoryCache(8578): キャッシュ サイズ=44032 長さ=1 04-09 10:44:33.140: D/ImageLoader(8578): ダウンロードの開始 hxxps://lh6.googleusercontent.com/-UBmLbPELvoQ/URqucCdv0kI/AAAAAAAAAbs/IdNhr2VQoQs /s1024/Apre%2525CC%252580s%252520la%252520Pluie.jpgcom/-UBmLbPELvoQ/URqucCdv0kI/AAAAAAAAAbs/IdNhr2VQoQs/s1024/Apre%2525CC%252580s%252520la%252520Pluie.jpg 04-09 10:44:33.140: I/MemoryCache(8578): キャッシュ サイズ=44032 長さ=1 04-09 10:44:33.140: D/ImageLoader(8578): ダウンロード開始com/-UBmLbPELvoQ/URqucCdv0kI/AAAAAAAAAbs/IdNhr2VQoQs/s1024/Apre%2525CC%252580s%252520la%252520Pluie.jpg 04-09 10:44:33.140: I/MemoryCache(8578): キャッシュ サイズ=44032 長さ=1 04-09 10:44:33.140: D/ImageLoader(8578): ダウンロード開始

https://github.com/nostra13/Android-Universal-Image-Loaderを使用

if (bmp != null && !bmp.isRecycled()) {
        Log.d("ImageLoader", " From Cache " + uri);
        if (configuration.loggingEnabled)
            L.i(LOG_LOAD_IMAGE_FROM_MEMORY_CACHE, memoryCacheKey);

        if (options.shouldPostProcess()) {
            ImageLoadingInfo imageLoadingInfo = new ImageLoadingInfo(uri, imageView, targetSize, options, listener,
                    engine.getLockForUri(uri));
            ProcessAndDisplayImageTask displayTask = new ProcessAndDisplayImageTask(engine, bmp, imageLoadingInfo, options.getHandler());
            engine.submit(displayTask);
        } else {
            options.getDisplayer().display(bmp, imageView);
            listener.onLoadingComplete(uri, imageView, bmp);
        }
    } else {
        Log.d("ImageLoader", " Begin Downloading " + uri);
        if (options.shouldShowStubImage()) {
            imageView.setImageResource(options.getStubImage());
        } else {
            if (options.isResetViewBeforeLoading()) {
                imageView.setImageBitmap(null);
            }
        }

        ImageLoadingInfo imageLoadingInfo = new ImageLoadingInfo(uri, imageView, targetSize, options, listener,
                engine.getLockForUri(uri));
        LoadAndDisplayImageTask displayTask = new LoadAndDisplayImageTask(engine, imageLoadingInfo, options.getHandler());
        engine.submit(displayTask);
    }

ListView を初期化すると、ログは次のようになります。

04-09 10:23:24.590: D/ImageLoader(7336): ダウンロード開始:24.600: D/ImageLoader(7336): ダウンロード開始(7336): ダウンロードを開始しますhxxps://lh6.googleusercontent.com/-55osAWw3x0Q/URquUtcFr5I/AAAAAAAAAbs/rWlj1RUKrYI/s1024/A%252520Photographer.jpg 04-09 10:23:24.610: D/ImageLoader(7336): ダウンロード開始 hxxps://lh6.グーグルユーザーコンテンツ。com/-55osAWw3x0Q/URquUtcFr5I/AAAAAAAAAbs/rWlj1RUKrYI/s1024/A%252520Photographer.jpg 04-09 10:23:24.610: D/ImageLoader(7336): ダウンロード開始 hxxps://lh6.googleusercontent.com/-UBmLbPELvoQ/URqucCdv0kI /AAAAAAAAAbs/IdNhr2VQoQs/s1024/Apre%2525CC%252580s%252520la%252520Pluie.jpg 04-09 10:23:24.610: D/ImageLoader(7336): ダウンロード開始 hxxps://lh6.googleusercontent.com/-UBmLbPELvoQ/URqucCdv0kI /AAAAAAAAAbs/IdNhr2VQoQs/s1024/Apre%2525CC%252580s%252520la%252520Pluie.jpgcom/-UBmLbPELvoQ/URqucCdv0kI/AAAAAAAAAbs/IdNhr2VQoQs/s1024/Apre%2525CC%252580s%252520la%252520Pluie.jpgcom/-UBmLbPELvoQ/URqucCdv0kI/AAAAAAAAAbs/IdNhr2VQoQs/s1024/Apre%2525CC%252580s%252520la%252520Pluie.jpg

したがって、httpRequest は Repeat....

4

1 に答える 1

0

Lazy Loading または Universal Image Loader を使用できます

Lazy List は、URL を使用して、sdcard または fomr サーバーから画像を遅延読み込みします。オンデマンドで画像を読み込むようなものです。

画像は、ローカル SD カードまたは電話メモリにキャッシュできます。URL がキーと見なされます。キーがSDカードからのSDカード表示画像に存在する場合は、サーバーからダウンロードして画像を表示し、選択した場所に同じ画像をキャッシュします。キャッシュ制限を設定できます。画像をキャッシュする独自の場所を選択することもできます。キャッシュもクリアできます。

ユーザーが大きな画像をダウンロードするのを待ってから遅延リストを表示する代わりに、オンデマンドで画像を読み込みます。画像領域がキャッシュされるため、画像をオフラインで表示できます。

https://github.com/thest1/LazyList . レイジーリスト

あなたのgetviewで

imageLoader.DisplayImage(imageurl, imageview); ImageLoader 表示方法

public void DisplayImage(String url, ImageView imageView) //url and imageview as parameters
{
imageViews.put(imageView, url);
Bitmap bitmap=memoryCache.get(url);   //get image from cache using url as key
if(bitmap!=null)         //if image exists
    imageView.setImageBitmap(bitmap);  //dispaly iamge
 else   //downlaod image and dispaly. add to cache.
 {
    queuePhoto(url, imageView);
    imageView.setImageResource(stub_id);
 }

Lazy List の代替は Universal Image Loader です

https://github.com/nostra13/Android-Universal-Image-Loader . Lazy List に基づいています (同じ原理で動作します)。しかし、それは他の多くの構成を持っています。より多くの構成オプションを提供するUniversal Image Loaderを使用することをお勧めします。ダウンロードに失敗した場合、エラー画像を表示できます。角を丸くした画像を表示できます。ディスクまたはメモリにキャッシュできます。画像を圧縮できます。

カスタム アダプター コンストラクターで

 File cacheDir = StorageUtils.getOwnCacheDirectory(a, "your folder");

// Get singletone instance of ImageLoader
imageLoader = ImageLoader.getInstance();
// Create configuration for ImageLoader (all options are optional)
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(a)
      // You can pass your own memory cache implementation
     .discCache(new UnlimitedDiscCache(cacheDir)) // You can pass your own disc cache implementation
     .discCacheFileNameGenerator(new HashCodeFileNameGenerator())
     .enableLogging()
     .build();
 // Initialize ImageLoader with created configuration. Do it once.
 imageLoader.init(config);
  options = new DisplayImageOptions.Builder()
.showStubImage(R.drawable.stub_id)//display stub image
.cacheInMemory()
.cacheOnDisc()
.displayer(new RoundedBitmapDisplayer(20))
 .build();

あなたの getView() で

 ImageView image=(ImageView)vi.findViewById(R.id.imageview); 
 imageLoader.displayImage(imageurl, image,options);//provide imageurl, imageview and options

ニーズに合わせて他のオプションを設定できます。

遅延読み込み/ユニバーサル イメージ ローダーに加えて、スムーズなスクロールとパフォーマンスのためにホルダーを表示できます。http://developer.android.com/training/improving-layouts/smooth-scrolling.html .

編集:

ご覧のとおり、画像は 2 回表示されます (1 回ダウンロードされます)。ただし、キャッシュされるのは一度だけです。以下の画像はアイコンです。テスト中に適切にスケーリングしていません。だから伸びて見える。

ここに画像の説明を入力

于 2013-04-08T09:33:16.830 に答える