Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Example using Androids lrucache

I need help understanding androids LruCache. I want to use to load images into my gridview in order make the loading/scrolling better. Can someone post an example code using LruCache please. Thanks in advance.

like image 379
MobDev Avatar asked Jul 24 '12 04:07

MobDev


People also ask

What is LRU cache in Android?

android.util.LruCache<K, V> A cache that holds strong references to a limited number of values. Each time a value is accessed, it is moved to the head of a queue. When a value is added to a full cache, the value at the end of that queue is evicted and may become eligible for garbage collection.

What is an LRU cache?

The Least Recently Used (LRU) cache is a cache eviction algorithm that organizes elements in order of use. In LRU, as the name suggests, the element that hasn't been used for the longest time will be evicted from the cache.

What is LRU cache Python?

LRU (Least Recently Used) Cache discards the least recently used items first. This algorithm requires keeping track of what was used when, which is expensive if one wants to make sure the algorithm always discards the least recently used item.


2 Answers

Below is a class I made for using LruCache, this is based on the presentation Doing More With Less: Being a Good Android Citizen given at Google I/O 2012.

Check out the movie for more information about what I'm doing in the TCImageLoader class:

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);         }     } } 
like image 178
ePeace Avatar answered Sep 28 '22 08:09

ePeace


I've found a really easy way that work perfectly for me...

This is the Cache.java class. In this class, the static getInstance() method enables us to create only one cache instance in the whole application. getLru() method is used to retrieve the cached object, it will be shown later how to use it. This cache is generic, meaning you can save any Object type into it. The cache memory size here is set to 1024. It can be changed if it is too small:

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;     } } 

This is the code in your activity where you save the bitmap to the cache:

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);     } 

This is the code where you retrieve the bitmap from the cache, then set an imageView to this bitmap:

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));  } 

THAT'S ALL! As you can see this is rather easy and simple.

  • EXAMPLE:

In my application, All the views are saved in class variables so they can be seen by all the methods in the class. In my first activity, I save the image bitmap to the cache in an onClickButton() method, right before I start a new activity using intent. I also save a string value in my cache:

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); } 

Then I navigate from the second activity to a third activity also using intents. In the last activity I save other objects into my cache, then go back to the first activity using an intent. Once I'm back in the first activity, the onCreate() method will start. In that method, I check if my cache has any bitmap value or any String value separately (based on my application business):

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...     } 
like image 31
Crystal Engineer Avatar answered Sep 28 '22 10:09

Crystal Engineer