创建一个返回位图的全局静态方法。此方法将接受参数:context、imageUrl 和 imageName。
在方法中:
-
检查文件是否已经存在于缓存中。如果是,则返回位图
if(new File(context.getCacheDir(), imageName).exists())
return BitmapFactory.decodeFile(new File(context.getCacheDir(), imageName).getPath());
-
否则,您必须从网络加载图像,并将其保存到缓存中:
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>> 对象,以及另一个List 持有imageUrls 和imageNames 的Map(供以后需要重新加载图片),然后设置您的 GridView 适配器。
我建议使用SoftReferences 的数组来减少使用的内存量。如果您有大量位图,您可能会遇到内存问题。
所以在你的getView 方法中,你可能有类似的东西(其中icons 是Vector 持有类型SoftReference<Bitmap>:
myImageView.setImageBitmap(icons.get(position).get());
您需要进行检查:
if(icons.get(position).get() == null) {
myImageView.setImageBitmap(defaultBitmap);
new ReloadImageTask(context).execute(position);
}
在ReloadImageTask AsyncTask 类中,只需使用正确的参数调用从上面创建的全局方法,然后在onPostExecute 中调用notifyDataSetChanged
可能需要做一些额外的工作,以确保您不会在该 AsyncTask 已经为特定项目运行时启动它