Ejemplo usando lrucache de androides

Necesito ayuda para entender androids LruCache. Quiero utilizar para cargar imágenes en mi gridview para hacer la carga / desplazamiento mejor. ¿Puede alguien publicar un código de ejemplo usando LruCache por favor. Gracias por adelantado.

A continuación se muestra una clase que hice para usar LruCache, esto se basa en la presentación Hacer más con menos: ser un buen ciudadano Android dado en Google I / O 2012 .

Echa un vistazo a la película para obtener más información sobre lo que estoy haciendo en la clase TCImageLoader :

 public class TCImageLoader implements ComponentCallbacks2 { private TCLruCache cache; public TCImageLoader(Context context) { ActivityManager am = (ActivityManager) context.getSystemService( Context.ACTIVITY_SERVICE); int maxKb = am.getMemoryClass() * 1024; int limitKb = maxKb / 8; // 1/8th of total ram cache = new TCLruCache(limitKb); } public void display(String url, ImageView imageview, int defaultresource) { imageview.setImageResource(defaultresource); Bitmap image = cache.get(url); if (image != null) { imageview.setImageBitmap(image); } else { new SetImageTask(imageview).execute(url); } } private class TCLruCache extends LruCache<String, Bitmap> { public TCLruCache(int maxSize) { super(maxSize); } @Override protected int sizeOf(ImagePoolKey key, Bitmap value) { int kbOfBitmap = value.getByteCount() / 1024; return kbOfBitmap; } } private class SetImageTask extends AsyncTask<String, Void, Integer> { private ImageView imageview; private Bitmap bmp; public SetImageTask(ImageView imageview) { this.imageview = imageview; } @Override protected Integer doInBackground(String... params) { String url = params[0]; try { bmp = getBitmapFromURL(url); if (bmp != null) { cache.put(url, bmp); } else { return 0; } } catch (Exception e) { e.printStackTrace(); return 0; } return 1; } @Override protected void onPostExecute(Integer result) { if (result == 1) { imageview.setImageBitmap(bmp); } super.onPostExecute(result); } private Bitmap getBitmapFromURL(String src) { try { URL url = new URL(src); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setDoInput(true); connection.connect(); InputStream input = connection.getInputStream(); Bitmap myBitmap = BitmapFactory.decodeStream(input); return myBitmap; } catch (IOException e) { e.printStackTrace(); return null; } } } @Override public void onConfigurationChanged(Configuration newConfig) { } @Override public void onLowMemory() { } @Override public void onTrimMemory(int level) { if (level >= TRIM_MEMORY_MODERATE) { cache.evictAll(); } else if (level >= TRIM_MEMORY_BACKGROUND) { cache.trimToSize(cache.size() / 2); } } } 

He encontrado una manera muy fácil que funciona perfectamente para mí …

Esta es la clase Cache.java. En esta clase, el método estático getInstance() nos permite crear sólo una instancia de caché en toda la aplicación. getLru() método getLru() se utiliza para recuperar el objeto en caché, se mostrará más adelante cómo usarlo. Este caché es genérico, lo que significa que puede guardar cualquier tipo de objeto en él. El tamaño de memoria caché aquí se establece en 1024. Se puede cambiar si es demasiado pequeño:

 import android.support.v4.util.LruCache; public class Cache { private static Cache instance; private LruCache<Object, Object> lru; private Cache() { lru = new LruCache<Object, Object>(1024); } public static Cache getInstance() { if (instance == null) { instance = new Cache(); } return instance; } public LruCache<Object, Object> getLru() { return lru; } } 

Este es el código de la actividad en la que guarda el mapa de bits en la memoria caché:

 public void saveBitmapToCahche(){ //The imageView that you want to save it's bitmap image resourse ImageView imageView = (ImageView) findViewById(R.id.imageViewID); //To get the bitmap from the imageView Bitmap bitmap = ((BitmapDrawable)imageview.getDrawable()).getBitmap(); //Saving bitmap to cache. it will later be retrieved using the bitmap_image key Cache.getInstance().getLru().put("bitmap_image", bitmap); } 

Este es el código en el que recupera el mapa de bits de la memoria caché y, a continuación, establece un imageView en este mapa de bits:

 public void retrieveBitmapFromCache(){ //The imageView that you want to set to the retrieved bitmap ImageView imageView = (ImageView) findViewById(R.id.imageViewID); //To get bitmap from cache using the key. Must cast retrieved cache Object to Bitmap Bitmap bitmap = (Bitmap)Cache.getInstance().getLru().get("bitmap_image"); //Setting imageView to retrieved bitmap from cache imageView.setImageBitmap(bitmap)); } 

¡ESO ES TODO! Como puede ver esto es bastante fácil y simple.

  • EJEMPLO:

En mi aplicación, todas las vistas se guardan en las variables de clase para que puedan ser vistas por todos los métodos de la clase. En mi primera actividad, onClickButton() el mapa de bits de imagen en la memoria caché en un método onClickButton() , justo antes de iniciar una nueva actividad con la intención. También guardo un valor de cadena en mi caché:

 public void onClickButton(View v){ Bitmap bitmap = ((BitmapDrawable)imageView.getDrawable()).getBitmap(); String name = textEdit.getText().toString(); Cache.getInstance().getLru().put("bitmap_image", bitmap); Cache.getInstance().getLru().put("name", name); Intent i = new Intent(FirstActivity.this, SecondActivity.class); startActivity(i); } 

Luego navego de la segunda actividad a una tercera actividad también usando intentos. En la última actividad guardo otros objetos en mi caché, luego vuelvo a la primera actividad usando una intención. Una vez que estoy de vuelta en la primera actividad, el método onCreate() se iniciará. En ese método, comprobar si mi caché tiene algún valor de mapa de bits o cualquier valor de cadena por separado (en función de mi negocio de aplicaciones):

 public ImageView imageView; public EditText editText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_first); //...Other code... //The imageView that you want to save it's bitmap image resourse imageView = (ImageView) findViewById(R.id.imageViewID); //The editText that I want to save it's text into cache editText = (EditText)findViewById(R.id.editTextID); if(Cache.getInstance().getLru().get("name")!=null){ editText.setText(Cache.getInstance().getLru().get("name").toString()); } if(Cache.getInstance().getLru().get("bitmap_image")!=null){ imageView.setImageBitmap((Bitmap)Cache.getInstance().getLru().get("bitmap_image")); } //...Other code... } 

Echa un vistazo a Cache Bitmaps donde se demuestra el uso de LruCache .

La parte pertinente del código de la página es la siguiente:

 private LruCache mMemoryCache; @Override protected void onCreate(Bundle savedInstanceState) { ... // Get memory class of this device, exceeding this amount will throw an // OutOfMemory exception. final int memClass = ((ActivityManager) context.getSystemService( Context.ACTIVITY_SERVICE)).getMemoryClass(); // Use 1/8th of the available memory for this memory cache. final int cacheSize = 1024 * 1024 * memClass / 8; mMemoryCache = new LruCache(cacheSize) { @Override protected int sizeOf(String key, Bitmap bitmap) { // The cache size will be measured in bytes rather than number of items. return bitmap.getByteCount(); } }; ... } public void addBitmapToMemoryCache(String key, Bitmap bitmap) { if (getBitmapFromMemCache(key) == null) { mMemoryCache.put(key, bitmap); } } public Bitmap getBitmapFromMemCache(String key) { return mMemoryCache.get(key); } 

https://techienotes.info/2015/08/28/caching-bitmaps-in-android-using-lrucache/

Este enlace tiene un proyecto completo que tiene una aplicación de ejemplo para cargar imágenes en Gridview usando LruCache.

Esta clase está usando LruCache y tomada del código dado en el enlace

 public class ImageAdapter extends BaseAdapter{ private String TAG = getClass().getSimpleName(); Context mContext; ArrayList<Uri> imageList; private LruCache<String, Bitmap> mLruCache; public ImageAdapter (Context context){ mContext = context; //Find out maximum memory available to application //1024 is used because LruCache constructor takes int in kilobytes final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); // Use 1/4th of the available memory for this memory cache. final int cacheSize = maxMemory / 4; Log.d(TAG, "max memory " + maxMemory + " cache size " + cacheSize); // LruCache takes key-value pair in constructor // key is the string to refer bitmap // value is the stored bitmap mLruCache = new LruCache<String, Bitmap>(cacheSize) { @Override protected int sizeOf(String key, Bitmap bitmap) { // The cache size will be measured in kilobytes return bitmap.getByteCount() / 1024; } }; imageList = new ArrayList<Uri>(); //Change this directory to where the images are stored String imagesFolderPath = Environment.getExternalStorageDirectory().getPath()+"/backups/"; File imageSrcDir = new File (imagesFolderPath); // if directory not present, build it if (!imageSrcDir.exists()){ imageSrcDir.mkdirs(); } ArrayList<File> imagesInDir = getImagesFromDirectory(imageSrcDir); for (File file: imagesInDir){ // imageList will hold Uri of all images imageList.add(Uri.fromFile(file)); } } @Override public int getCount() { return imageList.size(); } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return 0; } /** * * @param position The position of the item within the * adapter's data set of the item whose view we want. * @param convertView it is the view to be reused * @param parent The parent that this view will eventually be attached to * @return a View corresponding to the data at the specified position. */ @Override public View getView(int position, View convertView, ViewGroup parent) { ImageView imageView; Bitmap thumbnailImage = null; if (convertView == null){ imageView = new ImageView(mContext); imageView.setLayoutParams( //150,150 is size of imageview to display image new GridView.LayoutParams(150, 150)); imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); } else { imageView = (ImageView)convertView; } // Use the path as the key to LruCache final String imageKey = imageList.get(position).toString(); //thumbnailImage is fetched from LRU cache thumbnailImage = getBitmapFromMemCache(imageKey); if (thumbnailImage == null){ // if asked thumbnail is not present it will be put into cache BitmapWorkerTask task = new BitmapWorkerTask(imageView); task.execute(imageKey); } imageView.setImageBitmap(thumbnailImage); return imageView; } /** * This function returns the files from a directory * @param parentDirPath source directory in which images are located * @return list of Files */ private ArrayList<File> getImagesFromDirectory (File parentDirPath){ ArrayList <File> listOfImages = new ArrayList<File>(); File [] fileArray = null; if ( parentDirPath.isDirectory() ){//parentDirPath.exists() && // && // parentDirPath.canRead()){ fileArray = parentDirPath.listFiles(); } if (fileArray == null){ return listOfImages; // return empty list } for (File file: fileArray){ if (file.isDirectory()){ listOfImages.addAll(getImagesFromDirectory(file)); } else { // Only JPEG and PNG formats are included // for sake of simplicity if (file.getName().endsWith("png") || file.getName().endsWith("jpg")){ listOfImages.add(file); } } } return listOfImages; } /** * This function will return the scaled version of original image. * Loading original images into thumbnail is wastage of computation * and hence we will take put scaled version. */ private Bitmap getScaledImage (String imagePath){ Bitmap bitmap = null; Uri imageUri = Uri.parse (imagePath); try{ BitmapFactory.Options options = new BitmapFactory.Options(); /** * inSampleSize flag if set to a value > 1, * requests the decoder to sub-sample the original image, * returning a smaller image to save memory. * This is a much faster operation as decoder just reads * every n-th pixel from given image, and thus * providing a smaller scaled image. * 'n' is the value set in inSampleSize * which would be a power of 2 which is downside * of this technique. */ options.inSampleSize = 4; options.inScaled = true; InputStream inputStream = mContext.getContentResolver().openInputStream(imageUri); bitmap = BitmapFactory.decodeStream(inputStream, null, options); } catch (FileNotFoundException e) { e.printStackTrace(); } return bitmap; } public void addBitmapToMemoryCache(String key, Bitmap bitmap) { if (getBitmapFromMemCache(key) == null) { mLruCache.put(key, bitmap); } } public Bitmap getBitmapFromMemCache(String key) { return mLruCache.get(key); } class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> { private final WeakReference<ImageView> imageViewReference; public BitmapWorkerTask(ImageView imageView) { // Use a WeakReference to ensure the ImageView can be garbage collected imageViewReference = new WeakReference<ImageView>(imageView); } @Override protected Bitmap doInBackground(String... params) { final Bitmap bitmap = getScaledImage(params[0]); addBitmapToMemoryCache(String.valueOf(params[0]), bitmap); return bitmap; } // onPostExecute() sets the bitmap fetched by doInBackground(); @Override protected void onPostExecute(Bitmap bitmap) { if (imageViewReference != null && bitmap != null) { final ImageView imageView = (ImageView)imageViewReference.get(); if (imageView != null) { imageView.setImageBitmap(bitmap); } } } } } 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.