我正在使用以下示例在我的活动中显示互联网图像.
http://developer.android.com/resources/tutorials/views/hello-gridview.html
在自定义图像适配器中,我直接从Internet加载图像并将其分配给imageview.
在gridview中显示图像,并且每件事情都很好,但它不是有效的方式.
当我滚动gridview它一次又一次加载图像,这就是为什么gridview滚动非常慢
是否有缓存或一些有用的技术可以使它更快?
解决方法
创建一个返回Bitmap的全局静态方法.此方法将采用参数:context,imageUrl和imageName.
在方法中:
>检查文件是否已存在于缓存中.如果是,返回位图
if(new File(context.getCacheDir(),imageName).exists()) return BitmapFactory.decodeFile(new File(context.getCacheDir(),imageName).getPath());
>否则您必须从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;
预加载Vector< SoftReference< Bitmap>>使用上述方法在AsyncTask类中使用所有位图的对象,以及另一个包含imageUrls和imageNames的Map的List(以便在需要重新加载图像时进行访问),然后设置GridView适配器.
我建议使用一组SoftReferences来减少使用的内存量.如果你有大量的位图,你可能会遇到内存问题.
所以在你的getView方法中,你可能有类似的东西(其中图标是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
FileOutputStream fos = null; try { fos = new FileOutputStream(new File(context.getCacheDir(),R.drawable.default_cached_image); } fos.flush(); fos.close(); return image;myImageView.setImageBitmap(icons.get(position).get());if(icons.get(position).get() == null) { myImageView.setImageBitmap(defaultBitmap); new ReloadImageTask(context).execute(position); }