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

我正在使用以下示例在我的活动中显示Internet图像。

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

在自定义图像适配器,我直接从互联网加载图像,并将其分配给imageview。

在GridView中显示图像,每件事情都很好,但效率不高。

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

有没有caching或一些有用的技术,使其更快?

Solutions Collecting From Web of "如何有效地在gridview中加载互联网图像?"

创build一个返回一个Bitmap的全局静态方法。 该方法将采用参数: contextimageUrlimageName

在方法中:

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

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

     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; 

AsyncTask类中使用上述方法预载所有Vector<SoftReference<Bitmap>>Vector<SoftReference<Bitmap>>对象,另一个List保存imageUrls和imageNames的Map (以便稍后在需要重新加载图像时访问),然后设置您的GridView适配器。

我build议使用SoftReferences数组来减less使用的内存量。 如果你有大量的位图,你可能会遇到内存问题。

所以在你的getView方法中,你可能有类似的东西(其中icons是一个Vectortypes的SoftReference<Bitmap>

 myImageView.setImageBitmap(icons.get(position).get()); 

你需要做一个检查:

 if(icons.get(position).get() == null) { myImageView.setImageBitmap(defaultBitmap); new ReloadImageTask(context).execute(position); } 

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

一些额外的工作可能需要完成,以确保当它已经运行一个特定的项目时,不会启动这个AsyncTask

你将需要自己实现caching。 创build一个将下载图像的代理类。 在getView中请求这个类通过传递一个url来下载一个图片。 在代理类中创build一个HashMap,将一个URL映射到一个位图。 如果传递的url的关键字不存在,请下载并保存图像。 否则返回存储的位图转换为一个imageView。

当然,你不能存储尽可能多的图像,只要你喜欢。 您需要根据您期望的图像大小设置一个限制,例如10个图像。 当超过限制时,您需要丢弃旧图像在新的。

你可以试试DroidFu。 我的应用程序使用ImageCache。 还有一些基于web的imageview或者库中的某种方式。 特别参见WebImageView和WebGalleryAdapter: http ://mttkay.github.com/droid-fu/index-all.html

编辑补充说:droid-fu项目不赞成使用Ignition。 https://github.com/mttkay/ignition