如何解决延迟加载的位图的VM预算内存堆错误? [英] How to solve the vm budget memory heap error in lazy loading bitmaps?

查看:139
本文介绍了如何解决延迟加载的位图的VM预算内存堆错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在使用图像加载器类延迟加载列表视图中。它工作正常,但我一直在处理大量位图将被从Web服务下载。所以现在我得到的位图的大小超过VM预算。增加bitmapfactory尺寸为32 * 1024,但如果它再次达到32MB就会抛出一个错误。它被打破我的头在过去的一个星期。所以有人请帮我出这个问题。我在这里通过张贴我的图像加载类以及请让我知道,我应该怎么解决这个问题。

 公共类ImageLoader的{

私人的HashMap<字符串,位图>缓存=新的HashMap<字符串,位图>();
点阵位图= NULL;

私人活动的活动;
PhotosLoader photoLoaderThread =新PhotosLoader();
公共ImageLoader的(活动活动){
    this.activity =活动;
    photoLoaderThread.setPriority(Thread.NORM_PRIORITY-1);
    清除缓存();
}
公共无效DisplayImage(字符串URL,活动活动,ImageView的ImageView的,的String [] IMAGEURL){
    this.activity =活动;
    如果(cache.containsKey(URL)){
        imageView.setImageBitmap(cache.get(URL));

    }
其他{
        imageView.setImageResource(R.drawable.icon);
        queuePhoto(URL,活动,ImageView的);
    }

}

私人无效queuePhoto(字符串URL,活动活动,ImageView的ImageView的){
    this.activity =活动;
    photosQueue.Clean(ImageView的);
    PhotoToLoad P =新PhotoToLoad(URL,ImageView的);
    同步(photosQueue.photosToLoad){
        photosQueue.photosToLoad.push(对);
        photosQueue.photosToLoad.notifyAll();
    }
    如果(photoLoaderThread.getState()== Thread.State.NEW)
        photoLoaderThread.start();
}

公共位图getBitmap(字符串URL,诠释的采样大小)抛出异常{
    位图BM = NULL;
    尝试 {
        URL请求=新的网址(URL);
        InputStream的是=(的InputStream)request.getContent();
        BitmapFactory.Options选项=新BitmapFactory.Options();
        options.inDither = TRUE;
        options.inPurgeable = TRUE;
        options.inInputShareable = TRUE;
        options.inSampleSize =采样大小;
        options.inTempStorage =新的字节[32 * 1024];

        BM = BitmapFactory.de codeStream(是,空,期权);
        如果(BM!= NULL)
        BM = Bitmap.createScaledBitmap(BM,115 100,真正的);
        is.close();
        是=无效;
    }赶上(IOException异常E){
        抛出新的异常();
    }赶上(OutOfMemoryError异常E){
        bm.recycle();
        BM = NULL;
        System.gc()的;
        抛出新的异常();
    }
    返回BM;
}
私有类PhotoToLoad {
    公共字符串URL;
    公众的ImageView ImageView的;
    公共PhotoToLoad(字符串U,ImageView的我){
        URL = U;
        ImageView的=我;
    }
}
PhotosQueue photosQueue =新PhotosQueue();
公共无效stopThread(){
    photoLoaderThread.interrupt();
}
静态类PhotosQueue {
    私人堆叠式和LT; PhotoToLoad> photosToLoad =新的堆栈< PhotoToLoad>();
    公共无效清洁(ImageView的图像){
        对于(INT J = 0; J< photosToLoad.size()){
            尝试{
            如果(photosToLoad.get(J).imageView ==图片)
                photosToLoad.remove(J);
            其他
                + D];
            }赶上(例外五){
            }
        }
    }
}
类PhotosLoader继承Thread {
    公共无效的run(){
        尝试 {
            而(真){

                如果(photosQueue.photosToLoad.size()== 0)
                    同步(photosQueue.photosToLoad){
                        photosQueue.photosToLoad.wait();
                    }
                如果(photosQueue.photosToLoad.size()!= 0){
                    PhotoToLoad photoToLoad;
                    同步(photosQueue.photosToLoad){
                        photoToLoad = photosQueue.photosToLoad.pop();
                    }
                    BMP位= NULL;
                        BMP = getBitmap(photoToLoad.url,1);
                    cache.put(photoToLoad.url,BMP);
                    如果(((字符串)photoToLoad.imageView.getTag())。等于(photoToLoad.url)){
                        BitmapDisplayer BD =新BitmapDisplayer(BMP,photoToLoad.imageView);
                        活动一=(活动)photoToLoad.imageView.getContext();
                        a.runOnUiThread(BD);
                    }
                }
                如果(Thread.interrupted())
                    打破;
            }
        }赶上(InterruptedException异常E){
            e.printStackTrace();
        }赶上(例外五){
            e.printStackTrace();
        }
    }
}


类BitmapDisplayer实现Runnable {
    ImageView的ImageView的;
    公共BitmapDisplayer(位图B,ImageView的我){
        位= NULL;
        位= B;
        ImageView的=我;
        }
    公共无效的run(){
        如果(位图!= NULL){
            imageView.setImageBitmap(位);
            imageView.setScaleType(ScaleType.FIT_XY);
        }
        其他{
            imageView.setImageResource(R.drawable.icon);
        }
    }
}

公共无效clearCache(){
    尝试{
    cache.clear();
    缓存=新的HashMap<字符串,位图>();
    bitmap.recycle();
    System.gc()的;
    }赶上(例外五){
    }
}
 

解决方案

下面links..u验证可以得到的想法有关...

http://negativeprobability.blogspot.com/2011/08/lazy-loading-of-images-in-listview.html http://stackoverflow.com/questions/5082703/android-out-of-memory-error-with-lazy-load-images HTTP://blog.jteam。 NL / 2009/09/17 /探索最世界的,Android的部分-2 / http://groups.google.com/group/android-developers/browse_thread/thread/bb3c57cab27e0d91?fwc=1

I have been using Image loader class for lazy loading in list view. It works fine but I have been dealing with lots of bitmap that will be downloaded from web service. so now I get bitmap size exceeds VM budget. Increased bitmapfactory size to be 32*1024 but if it reaches 32mb again it will throw a the error. It being breaking my head for the past one week. so some one please help me out of this problem. I here by post my image loader class as well please let me know where and how should I solve this problem.

public class ImageLoader {

private HashMap<String, Bitmap> cache=new HashMap<String, Bitmap>();
Bitmap bitmap = null;

private Activity activity;
PhotosLoader photoLoaderThread=new PhotosLoader();
public ImageLoader(Activity activity){
    this.activity = activity;
    photoLoaderThread.setPriority(Thread.NORM_PRIORITY-1);
    clearCache();
}
public void DisplayImage(String url, Activity activity, ImageView imageView, String[] imageUrl){
    this.activity = activity;
    if(cache.containsKey(url)){
        imageView.setImageBitmap(cache.get(url));

    }
else{
        imageView.setImageResource(R.drawable.icon);
        queuePhoto(url, activity, imageView);
    }    

}

private void queuePhoto(String url, Activity activity, ImageView imageView){
    this.activity = activity;
    photosQueue.Clean(imageView);
    PhotoToLoad p=new PhotoToLoad(url, imageView);
    synchronized(photosQueue.photosToLoad){
        photosQueue.photosToLoad.push(p);
        photosQueue.photosToLoad.notifyAll();
    }
    if(photoLoaderThread.getState()==Thread.State.NEW)
        photoLoaderThread.start();
}

public Bitmap getBitmap(String url, int sampleSize) throws Exception{
    Bitmap bm = null;
    try {
        URL request = new URL(url);
        InputStream is = (InputStream) request.getContent();
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inDither = true;
        options.inPurgeable = true;
        options.inInputShareable = true;
        options.inSampleSize = sampleSize;
        options.inTempStorage = new byte[32 * 1024];

        bm = BitmapFactory.decodeStream(is, null, options);
        if (bm!=null)
        bm = Bitmap.createScaledBitmap(bm, 115,100, true);
        is.close();
        is = null;
    } catch (IOException e) {
        throw new Exception();
    } catch (OutOfMemoryError e) {
        bm.recycle();
        bm = null;
        System.gc();
        throw new Exception();
    }
    return bm;
}
private class PhotoToLoad{
    public String url;
    public ImageView imageView;
    public PhotoToLoad(String u, ImageView i){
        url=u; 
        imageView=i;
    }
}
PhotosQueue photosQueue=new PhotosQueue();
public void stopThread(){
    photoLoaderThread.interrupt();
}
static class  PhotosQueue{
    private Stack<PhotoToLoad> photosToLoad=new Stack<PhotoToLoad>();
    public void Clean(ImageView image){
        for(int j=0 ;j<photosToLoad.size();){
            try{
            if(photosToLoad.get(j).imageView==image)
                photosToLoad.remove(j);
            else
                ++j;
            }catch (Exception e) {
            }
        }
    }
}
class PhotosLoader extends Thread {
    public void run() {
        try {
            while(true){

                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 = null;
                        bmp = getBitmap(photoToLoad.url, 1);
                    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) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


class BitmapDisplayer implements Runnable{
    ImageView imageView;
    public  BitmapDisplayer(Bitmap b, ImageView i){
        bitmap = null;
        bitmap=b;
        imageView=i;
        }
    public void run(){
        if(bitmap!=null){
            imageView.setImageBitmap(bitmap);
            imageView.setScaleType(ScaleType.FIT_XY);
        }
        else{
            imageView.setImageResource(R.drawable.icon);
        }
    }
}

public void clearCache() {
    try{
    cache.clear();
    cache = new HashMap<String, Bitmap>();
    bitmap.recycle();   
    System.gc();
    }catch (Exception e) {
    }
}

解决方案

verify below links..u can get idea about that...

http://negativeprobability.blogspot.com/2011/08/lazy-loading-of-images-in-listview.html http://stackoverflow.com/questions/5082703/android-out-of-memory-error-with-lazy-load-images http://blog.jteam.nl/2009/09/17/exploring-the-world-of-android-part-2/ http://groups.google.com/group/android-developers/browse_thread/thread/bb3c57cab27e0d91?fwc=1

这篇关于如何解决延迟加载的位图的VM预算内存堆错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆