簡體   English   中英

android-使用UniversalImageLoader將位圖加載到ArrayList時的延遲

[英]android - delay while loading Bitmaps into ArrayList using UniversalImageLoader

我需要將位圖加載到ArrayList中,然后將其轉換為Bitmap []並傳遞到ArrayAdapter中以膨脹ListView。 我使用UniversalImageLoader庫,這是我的代碼:

final ArrayList<Bitmap> imgArray = new ArrayList<>(); //before the method scope, as a class field
//...some code...
File cacheDir = StorageUtils.getOwnCacheDirectory(
            getApplicationContext(),
            "/sdcard/Android/data/random_folder_for_cache");

    DisplayImageOptions options = new DisplayImageOptions.Builder()
            .cacheInMemory(true).cacheOnDisc(true).build();

    ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
            getApplicationContext()).defaultDisplayImageOptions(options)
            //.discCache(new FileCounterLimitedCache(cacheDir, 100)) - I commented it 'cause FileCounterLimitedCache isn't recognized for some reason
            .build();
    ImageLoader.getInstance().init(config);

    for (int num=0;num<4;num++) {
        ImageLoader imageLoader = ImageLoader.getInstance();
        final int constNum = num;
        imageLoader.loadImage("http://example.com/sample.jpg", new SimpleImageLoadingListener()
        {
            @Override
            public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage)
            {
                imgArray.add(constNum, loadedImage);
            }
        });
    }

但是我有一些問題需要解決。 首先,它在第一次運行時經常返回錯誤(IndexOutOfBoundsException-當前索引超過ArrsyList的大小)。 然后,經過一段時間(大約一分鍾),ArrayList的大小為1(我用Toast對其進行了檢查),然后立即再次運行時,它的大小已經為4(需要這樣)。 奇怪。 但是最主要的是,我需要先填充ArrayList,然后再完成所有其他操作(將它們延遲,並且在第一次運行時沒有錯誤)。 怎么做?

如果有人沒有SD卡怎么辦? 順便說一句,我在SD上找不到創建的緩存文件夾...

您無法以嘗試的方式添加元素。 例如,如果第二張圖像首先完成加載,則您的代碼將正確拋出IndexOutOfBoundsException因為您要添加的位置超出了當前大小-請參閱文檔

您可能最好使用初始化為元素數量的數組來查看,因為您知道它是4個元素-例如

final Bitmap[] imgArray = new Bitmap[4];

然后使用以下命令將元素添加到onLoadingComplete()

imgArray[constNum] = loadedImage;

您可以使用SparseArray而不是ArrayList來避免IndexOutOfBoundsException 我認為這就是您追求的目標:

final SparseArray<Bitmap> imgArray = new SparseArray<>(); //before the method scope, as a class field
int numberOfImages;
int numberOfLoadedImages;

//...some code...
File cacheDir = StorageUtils.getOwnCacheDirectory(
        getApplicationContext(),
        "/sdcard/Android/data/random_folder_for_cache");

DisplayImageOptions options = new DisplayImageOptions.Builder()
        .cacheInMemory(true).cacheOnDisc(true).build();

ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
        getApplicationContext()).defaultDisplayImageOptions(options)
        //.discCache(new FileCounterLimitedCache(cacheDir, 100)) - I commented it 'cause FileCounterLimitedCache isn't recognized for some reason
        .build();
ImageLoader.getInstance().init(config);

numberOfImages = 4;
numberOfLoadedImages = 0;

for (int num=0;num<4;num++) {
    ImageLoader imageLoader = ImageLoader.getInstance();
    final int constNum = num;
    imageLoader.loadImage("http://example.com/sample.jpg", new SimpleImageLoadingListener()
    {
        @Override
        public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage)
        {
            imgArray.put(constNum, loadedImage);
            numberOfLoadedImages++;
            if(numberOfImages == numberOfLoadedImages)
            {
                //Do all the other actions
            }
        }
    });
}

Universal Image Loader庫包含以下方法:

public void displayImage(java.lang.String uri, android.widget.ImageView imageView)

可以傳遞圖像網址和ImageView以在其上顯示圖像。 ImageView ,如果稍后將相同的ImageView傳遞給方法,但使用不同的url,則會發生兩種情況:

  1. 如果已經下載了舊圖像,則通常會將新圖像設置為ImageView。

  2. 如果仍在下載舊映像,庫將取消下載舊映像的http連接。 並開始下載新圖像。 (可以在LogCat中觀察到)。 使用適配器時,會發生此行為。

方法調用:

ImageLoader.getInstance().displayImage("http://hydra-media.cursecdn.com/dota2.gamepedia.com/b/bd/Earthshaker.png", imageView1);

組態:

如果未指定defaultDisplayImageOptions,則緩存將不起作用。 告訴圖書館在哪里保存這些圖像。 因為此庫具有從資產,可繪制對象或Internet加載圖像的選項:

DisplayImageOptions opts = new DisplayImageOptions.Builder().cacheInMemory(true).cacheOnDisk(true).build();

使用此選項,圖像將保存在應用程序中。 內部存儲器。 不必擔心設備是否帶有外部存儲器。

ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this)
                .defaultDisplayImageOptions(opts)
                .memoryCache(new LruMemoryCache(2 * 1024 * 1024))
                .memoryCacheSize(2 * 1024 * 1024)
                .diskCacheSize(50 * 1024 * 1024)
                .diskCacheFileCount(100)
                .writeDebugLogs()
                .build();

ImageLoader.getInstance().init(config);

我為此創建了一個工作的github存儲庫。 看看這個。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM