Android image caching - how?

I think they ask him and ask, but still there are things that I can not understand.

I tried two different approaches:

  • Save all images in memory, when a certain limit begins to exceed, start deleting them.
  • Let Android fix it with SoftReferences

In 2. it’s just cleaning them sometimes the second one that I give them! And I do not allocate too much - 30-40 images of 50x50 pixels.

Therefore, I stick to one thing. The question is, what is the limit?

  • Can I get some reliable information from the device about how much raster memory I have left in my memory? I did some research, watched the DDMS values, it just took up more space (unless I clean) until it exploded. At one point, only 200K remains, then the system provides 2M more ...
  • I am currently using some kind of heuristic solution based on device model or screen size. I think this is the end in the end. Got exceptions on some phones, completely free on others.
  • Is there a third solution, right?
+8
android
source share
5 answers

The most important question: are you recycle() -configuring your bitmaps? This is very important for pre-click applications (possibly after Gingerbread).

Observing Memory Management for the Android Apps Session from Google I / O 2011 helped me better understand the development features for Android.

This video mentions the MAT tool - Memory Analyzer - which is useful for determining if you have objects hanging in memory that have been leaked. Perhaps you have more than 30-40 that you think you have.

To view and / or register the current heap size, etc., I would suggest using the code in this answer about exceptions for Android Out of Memory .

+8
source share

Image caching was an important part of the application that I created and placed in the application store. The application must download the images and cache them both in memory and on the SD card, so that their scope goes beyond a single run.

The general idea was to add images to the Caching Manager, which: a) stores the image in an associative container (HashMap) using a metadata-based key and b) writes the image file to the SDCard,

In low memory conditions, I release the HashMap. However, images can still be retrieved from the SD_Card and cached into memory again.

I was able to do this without recycling and still do not see memory problems. As far as I understand, re-utilization is not needed, but it helps to get an earlier version of the memory used for "bitmap images" due to the fact that the allocation for bitmaps in operations with the Gingerbread preliminary pointer uses Native Memory. those. memory not included in the Dalvik heap. Thus, the garbage collector does not free this memory, but frees it from specific policies.

This is from the Cache_Manager class:

 public static synchronized void addImage(Bitmap b, String urlString, boolean bSaveToFile, IMAGE_TYPES eIT, boolean bForce) { String szKey = getKeyFromUrlString(urlString, eIT); if (false == m_hmCachedImages.containsKey(szKey) || bForce) { m_hmCachedImages.put(szKey, b); if (bSaveToFile) { boolean bIsNull = false; // Write a null object to disk to prevent future query for non-existent image. if (null == b) { try { bIsNull = true; b = getNullArt(); } catch (NullPointerException e) { e.printStackTrace(); throw e; } } // Don't force null art to disk if (false == File_Manager.imageExists(szKey) || (bForce && bIsNull == false)) File_Manager.writeImage(b, szKey); } } } 

// Here is an example writeImage () from the File_Manager class

 public static void writeImage(Bitmap bmp, String szFileName) { checkStorage(); if (false == mExternalStorageWriteable) { Log.e("FileMan", "No Writable External Device Available"); return; } try { // Create dirctory if doesn't exist String szFilePath = getFilesPath(); boolean exists = (new File(szFilePath)).exists(); if (!exists) { new File(szFilePath).mkdirs(); } // Create file File file = new File(szFilePath, szFileName); // Write to file FileOutputStream os = new FileOutputStream(file); bmp.compress(Bitmap.CompressFormat.PNG, 90, os); } catch (IOException e) { // Unable to create file, likely because // external storage is // not currently mounted. Log.e("FileMan", "Error writing file", e); } catch (Exception e) { e.printStackTrace(); throw e; } } 
+4
source share

The limit is related to the size of the VM heap on the device on which it is running, because it differs from the device to the device and the OS to the OS, it can vary from 16 MB (total for the application) to 256 MB + (on tablets).

You need to either hold it under the lower end, create different assemblies on the device, or check the application at runtime, what the markup is, and load the images accordingly.

There are methods for checking the amount of free space on the heap and size:

This API reference will help you with avilable methods:

http://developer.android.com/reference/android/app/ActivityManager.html#getMemoryClass

+2
source share

From a high-level point of view, loading and caching images is part of the GreenDroid framework . Check this.

0
source share

You can use WebView to display images, it has built-in caching. In addition, it supports 2-finger scaling and scrolling without special code.

-2
source share

All Articles