如何有效地加载gridview中的互联网图像?

UMA*_*MAR 7 android gridview

我正在使用以下示例在我的活动中显示互联网图像.

http://developer.android.com/resources/tutorials/views/hello-gridview.html

在自定义图像适配器中,我直接从Internet加载图像并将其分配给imageview.

在gridview中显示图像,并且每件事情都很好,但它不是有效的方式.

当我滚动gridview它一次又一次加载图像,这就是为什么gridview滚动非常慢

是否有缓存或一些有用的技术可以使它更快?

jam*_*mes 13

创建一个返回位图的全局静态方法.这种方法将采取参数:context,imageUrl,和imageName.

在方法中:

  1. 检查文件是否已存在于缓存中.如果是,返回位图

        if(new File(context.getCacheDir(), imageName).exists())
            return BitmapFactory.decodeFile(new File(context.getCacheDir(), imageName).getPath());
    
    Run Code Online (Sandbox Code Playgroud)
  2. 否则您必须从Web加载图像,并将其保存到缓存中:

    image = BitmapFactory.decodeStream(HttpClient.fetchInputStream(imageUrl));
    
    
    
    FileOutputStream fos = null;
    try {
        fos = new FileOutputStream(new File(context.getCacheDir(), imageName));
    }
    
    
    //this should never happen
    catch(FileNotFoundException e) {
        if(Constants.LOGGING)
            Log.e(TAG, e.toString(), e);
    }
    
    
    //if the file couldn't be saved
    if(!image.compress(Bitmap.CompressFormat.JPEG, 100, fos)) {
        Log.e(TAG, "The image could not be saved: " + imageName + " - " + imageUrl);
        image = BitmapFactory.decodeResource(context.getResources(), R.drawable.default_cached_image);
    }
    fos.flush();
    fos.close();
    
    
    return image;
    
    Run Code Online (Sandbox Code Playgroud)

Vector<SoftReference<Bitmap>>使用上面的方法在AsyncTask类中预加载具有所有位图的对象,还有另一个List使用MapimageUrls和imageNames(以便在需要重新加载图像时进行访问),然后设置GridView适配器.

我建议使用一个数组SoftReferences来减少使用的内存量.如果你有大量的位图,你可能会遇到内存问题.

所以在你的getView方法中,你可能有类似的东西(哪里iconsVector持有类型SoftReference<Bitmap>:

myImageView.setImageBitmap(icons.get(position).get());
Run Code Online (Sandbox Code Playgroud)

你需要做一个检查:

if(icons.get(position).get() == null) {
    myImageView.setImageBitmap(defaultBitmap);
    new ReloadImageTask(context).execute(position);
}
Run Code Online (Sandbox Code Playgroud)

ReloadImageTask AsyncTask类中,只需使用正确的参数调用从上面创建的全局方法,然后notifyDataSetChangedonPostExecute

可能需要执行一些额外的工作,以确保在已经为特定项运行时不启动此AsyncTask