Создайте глобальный и статический метод, который возвращает растровое изображение. Этот метод будет принимать параметры: 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));
<pre><code>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
, а также другой List
, содержащий Map
imageUrls и imageNames (для последующего доступа, когда вам необходимо перезагрузить изображение), затем установите адаптер 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
, просто вызовите глобальный метод, созданный сверху, с правильными параметрами, затем notifyDataSetChanged
в onPostExecute
может потребоваться выполнить дополнительную работу, чтобы не запускать этот AsyncTask, когда он уже запущен для определенного элемента