Используйте LruCache
для эффективного кэширования изображений. Вы можете прочитать о LruCache
на сайте разработчика Android
Я использовал приведенное ниже решение для загрузки и кэширования изображений в Android. Вы можете выполнить следующие шаги:
ШАГ 1:
сделать имя класса ImagesCache
. Я использовал Singleton object for this class
import android.graphics.Bitmap;
import android.support.v4.util.LruCache;
public class ImagesCache
{
private LruCache<String, Bitmap> imagesWarehouse;
private static ImagesCache cache;
public static ImagesCache getInstance()
{
if(cache == null)
{
cache = new ImagesCache();
}
return cache;
}
public void initializeCache()
{
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() /1024);
final int cacheSize = maxMemory / 8;
System.out.println("cache size = "+cacheSize);
imagesWarehouse = new LruCache<String, Bitmap>(cacheSize)
{
protected int sizeOf(String key, Bitmap value)
{
// The cache size will be measured in kilobytes rather than number of items.
int bitmapByteCount = value.getRowBytes() * value.getHeight();
return bitmapByteCount / 1024;
}
};
}
public void addImageToWarehouse(String key, Bitmap value)
{
if(imagesWarehouse != null && imagesWarehouse.get(key) == null)
{
imagesWarehouse.put(key, value);
}
}
public Bitmap getImageFromWarehouse(String key)
{
if(key != null)
{
return imagesWarehouse.get(key);
}
else
{
return null;
}
}
public void removeImageFromWarehouse(String key)
{
imagesWarehouse.remove(key);
}
public void clearCache()
{
if(imagesWarehouse != null)
{
imagesWarehouse.evictAll();
}
}
}
ШАГ 2:
создаст другой класс с именем DownloadImageTask, который используется, если растровое изображение недоступно в кэше, и будет загружать его отсюда:
public class DownloadImageTask extends AsyncTask<String, Void, Bitmap>
{
private int inSampleSize = 0;
private String imageUrl;
private BaseAdapter adapter;
private ImagesCache cache;
private int desiredWidth, desiredHeight;
private Bitmap image = null;
private ImageView ivImageView;
public DownloadImageTask(BaseAdapter adapter, int desiredWidth, int desiredHeight)
{
this.adapter = adapter;
this.cache = ImagesCache.getInstance();
this.desiredWidth = desiredWidth;
this.desiredHeight = desiredHeight;
}
public DownloadImageTask(ImagesCache cache, ImageView ivImageView, int desireWidth, int desireHeight)
{
this.cache = cache;
this.ivImageView = ivImageView;
this.desiredHeight = desireHeight;
this.desiredWidth = desireWidth;
}
@Override
protected Bitmap doInBackground(String... params)
{
imageUrl = params[0];
return getImage(imageUrl);
}
@Override
protected void onPostExecute(Bitmap result)
{
super.onPostExecute(result);
if(result != null)
{
cache.addImageToWarehouse(imageUrl, result);
if(ivImageView != null)
{
ivImageView.setImageBitmap(result);
}
else
{
}
if(adapter != null)
{
adapter.notifyDataSetChanged();
}
}
}
private Bitmap getImage(String imageUrl)
{
if(cache.getImageFromWarehouse(imageUrl) == null)
{
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
options.inSampleSize = inSampleSize;
try
{
URL url = new URL(imageUrl);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
InputStream stream = connection.getInputStream();
image = BitmapFactory.decodeStream(stream, null, options);
int imageWidth = options.outWidth;
int imageHeight = options.outHeight;
if(imageWidth > desiredWidth || imageHeight > desiredHeight)
{
System.out.println("imageWidth:"+imageWidth+", imageHeight:"+imageHeight);
inSampleSize = inSampleSize + 2;
getImage(imageUrl);
}
else
{
options.inJustDecodeBounds = false;
connection = (HttpURLConnection)url.openConnection();
stream = connection.getInputStream();
image = BitmapFactory.decodeStream(stream, null, options);
return image;
}
}
catch(Exception e)
{
Log.e("getImage", e.toString());
}
}
return image;
}
ШАГ 3: Использование от Activity
или Adapter
Примечание: Если вы хотите загрузить изображение из URL из Activity
Класс. Используйте второй конструктор DownloadImageTask
, но если вы хотите отобразить изображение из Adapter
, используйте первый конструктор DownloadImageTask
(например, у вас есть изображение в ListView
, и вы устанавливаете изображение из 'Adapter')
ИСПОЛЬЗОВАНИЕ ОТ ДЕЯТЕЛЬНОСТИ:
ImageView imv = (ImageView) findViewById(R.id.imageView);
ImagesCache cache = ImagesCache.getInstance();//Singleton instance handled in ImagesCache class.
cache.initializeCache();
String img = "your_image_url_here";
Bitmap bm = cache.getImageFromWarehouse(img);
if(bm != null)
{
imv.setImageBitmap(bm);
}
else
{
imv.setImageBitmap(null);
DownloadImageTask imgTask = new DownloadImageTask(cache, imv, 300, 300);//Since you are using it from `Activity` call second Constructor.
imgTask.execute(img);
}
ИСПОЛЬЗОВАНИЕ ИЗ АДАПТЕРА:
ImageView imv = (ImageView) rowView.findViewById(R.id.imageView);
ImagesCache cache = ImagesCache.getInstance();
cache.initializeCache();
String img = "your_image_url_here";
Bitmap bm = cache.getImageFromWarehouse(img);
if(bm != null)
{
imv.setImageBitmap(bm);
}
else
{
imv.setImageBitmap(null);
DownloadImageTask imgTask = new DownloadImageTask(this, 300, 300);//Since you are using it from `Adapter` call first Constructor.
imgTask.execute(img);
}
Примечание:
cache.initializeCache()
вы можете использовать это утверждение в самой первой Деятельности вашего приложения. После того, как вы инициализировали кеш, вам никогда не нужно будет инициализировать его каждый раз, если вы используете ImagesCache
instance.
Я никогда не разбираюсь в объяснениях, но надеюсь, что это поможет новичкам понять, как кешировать, используя LruCache
и его использование :)
EDIT:
В наши дни существуют очень известные библиотеки, известные как Picasso
и Glide
, которые можно использовать для очень эффективной загрузки изображений в приложении для Android. Попробуйте эту очень простую и полезную библиотеку Picasso для Android и Glide For Android . Вам не нужно беспокоиться о кэше изображений.
Picasso позволяет без проблем загружать изображения в ваше приложение - часто
в одной строке кода!
Glide, как и Picasso, может загружать и отображать изображения из многих
источники, а также заботиться о кэшировании и сохранении памяти
влияние при выполнении манипуляций с изображением. Он был использован официальным
Приложения Google (например, приложение для Google I / O 2015) и столь же популярны
как Пикассо. В этой серии мы рассмотрим различия и
Преимущества Glide перед Пикассо.
Вы также можете посетить блог для разницы между Glide и Picasso