3
\$\begingroup\$

I needed a quick caching mechanism to save a bitmap (picture). There was no way I could get the bitmap to the class where I need to upload it to the server so for the sake of organization and code cleanliness I created this. I have never seen this before implemented this way but to me this not only fits the purpose but seems to be a good way to do this. I am unsure and definitely want to find the best way to do this.

The image in this cache would be accessed roughly around 30 seconds to 2 minutes after it is stored, so I am not worried about it being garbage collected soon. That is why I used a soft reference but I needed it to stay for awhile just in case the user wanted to delay or lag a while before uploading the image. I understand it could return null if it was garbage-collected, which is an edge case for now.

public class ImageCacheUtils {

    private static SoftReference<Bitmap> imageReference;

    public static void cache(Bitmap bitmap) {
        imageReference = new SoftReference<Bitmap>(bitmap);
    }

    @Nullable
    public static Bitmap getImage() {
        return imageReference.get();
    }
}
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Caches are harder to implement correctly then it would first appear. Unless you have a compelling reason to do so, strongly consider an existing implementation. \$\endgroup\$
    – Eric Stein
    Commented Dec 29, 2015 at 4:11

1 Answer 1

2
\$\begingroup\$

There was no way I could get the bitmap to the class where I need to upload it to the server so for the sake of organization and code cleanliness I created this

This is pretty concerning to me as it implies that your object model and dependency graph might be a little wonky, but as that's likely a lot more complicated than the question immediately at hand, I'd like to make the same suggestion as Eric Stein: use an existing cache library. Guava would likely be a good place to start. It has crazy flexible cache capabilities.


Even if you don't use a preexisting cache, a proper caching class that gets instantiated and injected would ease testing concerns, make thread safety easier to reason about, loosen coupling, and just all around be better.

Here are the current (obvious) limitations you have:

  • What if you want to store more than 1 bitmap?
  • What if you want to have more than 1 cache?
  • Have you considered the thread safety aspect of this? References are atomic on the JVM, but I'm not actually sure if this is threadsafe in the sense of up to date observation. It's possible that a thread could get a coherent, but out of date read.
  • Unit testing this could get a bit nasty.
    • Luckily since the class is so simple, it wouldn't be too bad, but it would be strange that your tests for a consumer of this class would essentially have to rely on the implementation of ImageCacheUtils.
    • If you had concurrent unit tests, thread safety is once again a concern.

Given all this though, I think you've already mentioned your main limitation: you have no control at all over the life time of the object in your cache. You're basically subjected to the whims of the garbage collector, and to me, that would be a little scary. Getting null may be an almost unthinkable edge case now, but what happens when you change Java versions? What happens if you run it on a server that's running low on memory?


In short, the little cache-like-thing that you've made is a clean, simple enough implementation of what little it does, but I'm afraid that a proper cache might do a lot more than as appears on the surface.

Caching is crazy complicated, and if you continue down this path, you'll likely realize that this isn't sufficient for your true requirements (though I'm still skeptical that this is the most proper solution).

\$\endgroup\$
1
  • \$\begingroup\$ Thanks for the answer. I am a professional Android Developer and have never implemented a cache before. This is probably the most uncertain code I have in my code base this is why I wanted others opinions. There are other options now that I have searched it, just thought I'd give it a try first. Though this does work perfectly for now, you are right and I know that I would need something a bit better. Thanks again. \$\endgroup\$ Commented Dec 29, 2015 at 19:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.