0

こんにちは、キャッシュとディスクキャッシュも処理する大量の画像をロードするのに役立つクラスを提案してくれる人はいますか?

ImageLoderクラスを使用しましたが、すべての画像を読み込むのに効率的ではなく、VMEXCEEDエラーが発生します

私のクラスは下にあります

     public class ImageLoader1 {

String Url1;
// the simplest in-memory cache implementation. This should be replaced with
// something like SoftReference or BitmapOptions.inPurgeable(since 1.6)
public HashMap<String, Bitmap> cache = new HashMap<String, Bitmap>();

private File cacheDir;

public ImageLoader1(Context context, String Url) {
    // Make the background thead low priority. This way it will not affect
    // the UI performance
    photoLoaderThread.setPriority(Thread.NORM_PRIORITY - 1);
    Url1 = Url;
    // Find the dir to save cached images
    if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
        cacheDir = new File(android.os.Environment.getExternalStorageDirectory(), "LazyList");
    else
        cacheDir = context.getCacheDir();
    if (!cacheDir.exists())
        cacheDir.mkdirs();
}

final int stub_id = R.drawable.placeholder;

// ----Method for Displaying image
public void DisplayImage(String url, Activity activity, ImageView imageView) {
    if (cache.containsKey(url)) {
        // ---Sets a Bitmap as the content of this ImageView.
        imageView.setImageBitmap(cache.get(url));
    } else {
        queuePhoto(url, activity, imageView);
        // imageView.setImageResource(stub_id);
    }
}

public void DisplayImage1(String url, ImageView imageView) {
    if (cache.containsKey(url))
        // ---Sets a Bitmap as the content of this ImageView.
        imageView.setImageBitmap(cache.get(url));
    else {
        queuePhoto1(url, imageView);
        // imageView.setImageResource(stub_id);
    }
}

private void queuePhoto(String url, Activity activity, ImageView imageView) {
    // This ImageView may be used for other images before. So there may be
    // some old tasks in the queue. We need to discard them.
    photosQueue.Clean(imageView);
    PhotoToLoad p = new PhotoToLoad(url, imageView);
    synchronized (photosQueue.photosToLoad) {
        photosQueue.photosToLoad.push(p);
        photosQueue.photosToLoad.notifyAll();
    }

    // start thread if it's not started yet
    if (photoLoaderThread.getState() == Thread.State.NEW)
        photoLoaderThread.start();
}

private void queuePhoto1(String url, ImageView imageView) {
    // This ImageView may be used for other images before. So there may be
    // some old tasks in the queue. We need to discard them.
    photosQueue.Clean(imageView);
    PhotoToLoad p = new PhotoToLoad(url, imageView);
    synchronized (photosQueue.photosToLoad) {
        photosQueue.photosToLoad.push(p);
        photosQueue.photosToLoad.notifyAll();
    }

    // start thread if it's not started yet
    if (photoLoaderThread.getState() == Thread.State.NEW)
        photoLoaderThread.start();
}

private Bitmap getBitmap(String url) {
    // I identify images by hashcode. Not a perfect solution, good for the
    // demo.
    String filename = String.valueOf(url.hashCode());
    File f = new File(cacheDir, filename);

    // from SD cache
    Bitmap b = decodeFile(f);
    if (b != null)
        return b;

    // from web
    try {
        Bitmap bitmap = null;
        InputStream is = new URL(url).openStream();
        OutputStream os = new FileOutputStream(f);
        Utils.CopyStream(is, os);
        os.close();
        bitmap = decodeFile(f);
        return bitmap;
    } catch (Exception ex) {
        ex.printStackTrace();
        return null;
    }
}

// decodes image and scales it to reduce memory consumption
private Bitmap decodeFile(File f) {
    try {
        // decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(new FileInputStream(f), null, o);

        // Find the correct scale value. It should be the power of 2.
        final int REQUIRED_SIZE = 50;
        int width_tmp = o.outWidth, height_tmp = o.outHeight;
        int scale = 1;
        while (true) {
            if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE)
                break;
            width_tmp /= 2;
            height_tmp /= 2;
            scale++;
        }

        // decode with inSampleSize
        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize = scale;
        return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
    } catch (FileNotFoundException e) {
    }
    return null;
}

// Task for the queue
private class PhotoToLoad {
    public String url;
    public ImageView imageView;

    public PhotoToLoad(String u, ImageView i) {
        url = u;
        imageView = i;
    }
}

PhotosQueue photosQueue = new PhotosQueue();

// ---Method for stopping thread
public void stopThread() {
    photoLoaderThread.interrupt();
}

// stores list of photos to download
class PhotosQueue {
    private Stack<PhotoToLoad> photosToLoad = new Stack<PhotoToLoad>();

    // removes all instances of this ImageView
    public void Clean(ImageView image) {
        for (int j = 0; j < photosToLoad.size();) {
            if (photosToLoad.get(j).imageView == image)
                photosToLoad.remove(j);
            else
                ++j;
        }
    }
}

// ----class for photoLoading
class PhotosLoader extends Thread {
    public void run() {
        try {
            while (true) {
                // thread waits until there are any images to load in the
                // queue
                if (photosQueue.photosToLoad.size() == 0)
                    synchronized (photosQueue.photosToLoad) {
                        photosQueue.photosToLoad.wait();
                    }
                if (photosQueue.photosToLoad.size() != 0) {
                    PhotoToLoad photoToLoad;
                    synchronized (photosQueue.photosToLoad) {
                        photoToLoad = photosQueue.photosToLoad.pop();
                    }
                    Bitmap bmp = getBitmap(photoToLoad.url);
                    cache.put(photoToLoad.url, bmp);
                    if (((String) photoToLoad.imageView.getTag()).equals(photoToLoad.url)) {
                        BitmapDisplayer bd = new BitmapDisplayer(bmp, photoToLoad.imageView);
                        Activity a = (Activity) photoToLoad.imageView.getContext();
                        a.runOnUiThread(bd);
                    }
                }
                if (Thread.interrupted())
                    break;
            }
        } catch (InterruptedException e) {
            // allow thread to exit
        }
    }
}

PhotosLoader photoLoaderThread = new PhotosLoader();

// Used to display bitmap in the UI thread
class BitmapDisplayer implements Runnable {
    Bitmap bitmap;
    ImageView imageView;

    public BitmapDisplayer(Bitmap b, ImageView i) {
        bitmap = b;
        imageView = i;
    }

    public void run() {
        if (bitmap != null)
            imageView.setImageBitmap(bitmap);
        // else
        // imageView.setImageResource(stub_id);
    }
}

public void clearCache() {
    // clear memory cache
    cache.clear();

    // clear SD cache
    File[] files = cacheDir.listFiles();
    for (File f : files)
        f.delete();
}

}

4

2 に答える 2

3

Android-Universal-Image-Loaderを使用して、大量の画像を読み込むことができます。

[追加1]

以下のサンプルプロジェクトを見てください。連絡先の画像を取得し、リストビューにロードします。それはあなたに普遍的なイメージlaoderの使用法についての考えを与えるでしょう。

https://dl.dropbox.com/u/68130108/UniversalImageLoaderExample.rar

于 2012-12-21T13:36:44.957 に答える
1

talhakosenが言ったように、UniversalImageLoaderを使用してください。

Just download its JAR file add into your libs folder create instance of ImageLoader

for example:

ImageLoader imgLoader = ImageLoader.getInstance();
imgLoader.displayImage(url,imageView);
于 2012-12-21T13:54:49.130 に答える