在ListView中延迟加载图像

时间:2013-02-20 07:08:25

标签: android lazy-loading

我从stackoverflow中听到了这个答案:

Lazy load of images in ListView

和Github的相同:

https://github.com/thest1/LazyList

Basic Usage的最后一行,它说:

  

请只创建一个ImageLoader实例并重复使用它   你的申请。这样,图像缓存效率会更高。

我该怎么做?

我有很多ListView(10-15),到目前为止我在Adapter类中使用这种方式,如示例所示:

public ImageLoader imageLoader; 

    public LazyAdapter(Activity a, String[] d) {
        activity = a;
        data=d;
        inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        imageLoader=new ImageLoader(activity.getApplicationContext());
    }

我试过这样做:

在第一个类中创建一个静态变量,并在其他地方使用它:

Class first{
public static ImageLoader imageLoader;
}

Class LazyAdapter{

first.imageLoader = new ImageLoader(activity.getApplicationContext());
//use it
}

但是和创建不同的实例不一样吗?我的意思是我将在每个适配器中创建一个新实例,当然前一个实例已经消失(不再参考)。

那么,这是正确的使用方式吗?

修改

这也写在代码中:

public File getFile(String url){
    //I identify images by hashcode. Not a perfect solution, good for the demo.
    String filename=String.valueOf(url.hashCode());
    //Another possible solution (thanks to grantland)
    //String filename = URLEncoder.encode(url);
    File f = new File(cacheDir, filename);
    return f;

}

那么,我应该使用String filename = URLEncoder.encode(url); ??

  

//使用25%的可用堆大小

按堆大小表示RAM?或者可以分配给Applcation的MAX RAM(我读到的地方是19mb)。

因为根据设备(三星Galaxy GT-S5830)规格:

内部 - 158 MB存储空间,278 MB RAM

但是在日志中我得到了

01-23 06:23:45.679: I/MemoryCache(1712): MemoryCache will use up to 16.0MB

在代码中设置 25%

如果它像 25%的可用内存。然后在设置 - >应用程序 - >管理应用程序:

在底部,它表示 159MB使用了21MB免费

THANKYOU

4 个答案:

答案 0 :(得分:3)

原因,作者提到在整个应用程序中只使用一个ImageLoader类是创建ImageLoader类实例的时间,然后在内部创建MemoryCache对象,这意味着10次ImageLoader实例,然后10次MemoryCache对象。在LazyList项目中,1个MemoryCache对象为图像保留了1/4的App Heap内存。因此,由于许多MemoryCache实例,大多数app堆内存都已耗尽。在这里,我有一个解决您的问题的方法是使MemoryCache类成为Singleton Class,如下面的代码所示:

将MemoryCache中的构造函数更改为private,并进行以下修改。

private static MemoryCache mc;
    public static MemoryCache getMemoryCache()
    {
        if(mc==null)
        {
            mc = new MemoryCache();
        }
        return mc;
    }
    private MemoryCache(){
        //use 25% of available heap size
        setLimit(Runtime.getRuntime().maxMemory()/4);
    }

答案 1 :(得分:1)

您应该使用单例模式或仅在某个类中初始化静态变量,然后在任何地方使用它。

public LazyAdapter(Activity a, String[] d) {
    activity = a;
    data=d;
    inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    imageLoader= someClass.imageLoader;
}

答案 2 :(得分:0)

为什么不使用Factory method来创建singleton

ImageLoader.java

中试用此代码段
private synchronized static ImageLoader instance;

private ImageLoader(Context context) {
    this.context = context;
    fileCache = new FileCache(context);
    executorService = Executors.newFixedThreadPool(5);
}

public synchronized static ImageLoader getInstance(Context context) {
    if (instance == null)
        instance = new ImageLoader(context);
    return instance;
}

答案 3 :(得分:0)

你可以这样做:

public class ImageLoader {

    private static ImageLoader inst;
    private ImageLoader() {

    }

    public static ImageLoader getInstance() {
        if (inst == null)
            inst = new ImageLoader(Context);
        return inst;
    }
}

每当您想要ImageLoader的对象时,您只需要调用getInstance()方法:ImageLoader.getInstance()