I tried to learn as much as possible about Android development, with a particular focus on performance, as many applications on the Play Store are sluggish today. I found / was directed to many articles / videos.
One specific article on image caching: http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html
The author has a code available at: http://code.google.com/p/android-imagedownloader/source/browse/trunk/src/com/example/android/imagedownloader/ImageDownloader.java
Which Google seems to have taken the version and placed classes in its samples at: http://developer.android.com/resources/samples/XmlAdapters/src/com/example/android/xmladapters/ImageDownloader.html
In general, it is solid, except that I consider a drawback in caching. It uses a soft / hard cache, which puts / gets things in a hard cache, because the Android system quite often flushes the soft cache.
However, looking at the code, the question arises as to whether the hard cache will accidentally appear reset when creating an instance of the parent class.
Soft cache first:
// Soft cache for bitmaps kicked out of hard cache private final static ConcurrentHashMap<String, SoftReference<Bitmap>> sSoftBitmapCache = new ConcurrentHashMap<String, SoftReference<Bitmap>>(HARD_CACHE_CAPACITY / 2);
Now take a look at the hard cache:
// Hard cache, with a fixed maximum capacity and a life duration private final HashMap<String, Bitmap> sHardBitmapCache = new LinkedHashMap<String, Bitmap>(HARD_CACHE_CAPACITY / 2, 0.75f, true) { @Override protected boolean removeEldestEntry(LinkedHashMap.Entry<String, Bitmap> eldest) { if (size() > HARD_CACHE_CAPACITY) { // Entries push-out of hard reference cache are transferred to soft reference cache sSoftBitmapCache.put(eldest.getKey(), new SoftReference<Bitmap>(eldest.getValue())); return true; } else return false; } };
hard cache is not static , but soft cache is static. In this way, the hard cache instance and therefore the elements are cleared using the life of the class instance.
I believe it is true that I noticed that my ListView / ImageView application loads an image every time and never caches it. All this was done asynchronously, but still hit the network every time. I checked by putting the Log.d()
operator inside my method, which gets to the Internet and sees when / how often it was called.
Adding the static keyword fixed the problem and my application is much more efficient.
I'm not sure why this is so, since there is only one instance of the ImageDownloader class in my adapter, as shown in the example:
private final ImageDownloader imageDownloader = new ImageDownloader();
QUESTION
With all that said, has anyone else experienced this ??? Or am I somehow combining crazy / wrong. I'm not an expert on Java / Android / JVM / Dalvik / WeakReference / SoftReference, but something seems a bit off. I donβt know why sHardBitmapCache
not static, but when I made this change, my application stopped hitting the network so hard (saving on data costs / drainage / improving battery performance) .