現在Androidで画像を扱うアプリを作っているのですが、Androidの場合、画像を大量に扱うと、あっという間にメモりを使い果たしてOut of Memoryで強制終了してしまうという悲しい現実があります。画像をある程度キャッシュするようにしないと、毎回画像をインターネットからDLすることになってパフォーマンスは低下するし、かといってキャッシュするとOut of Memoryが発生する…。
Web+DB Press Vol.57で、onPauseのタイミングで大きなリソースは解放してしまい、小さなリソースのみキャッシュするというふうにするとOut of Memoryが発生しにくいというふうに書かれていたので、サムネイルのみキャッシュして、でかい画像は全くキャッシュしないように実装してみたのだけれど、どうもしっくりこない。やっぱりパフォーマンスが落ちるからでしょう。
パフォーマンス対策のみならずメモリ対策もどうしたらいいのかな〜と思案していたのですが、TechFirm Android LabさんのブログでSoftReferenceが紹介されていました。
SoftReferenceを使うと、メモリがOut of Memoryになりそうになると、優先的にGCされるそうです。これを使っておけば、Out of Memoryに悩まされることもなさそうです!BitmapオブジェクトをSoftReferenceでラップするようにして使うようです。
public class ImageCache { private static HashMap<String,SoftReference<Bitmap>> cache = new HashMap<String,SoftReference<Bitmap>>(); public static Bitmap getImage(String key) { if (cache.containsKey(key)) { SoftReference<Bitmap> ref = cache.get(key); if (ref != null) { return ref.get(); } } return null; } public static void setImage(String key, Bitmap image) { cache.put(key, new SoftReference<Bitmap>(image)); } public static boolean hasImage(String key) { return cache.containsKey(key); } public static void clear() { cache.clear(); } }
さっき画像を大量に扱うアクティビティで試してみたら、全く落ちなくなっていて感動です!あぁ〜、2週間前から知っていたらなぁ〜。いや、そういう経験を積んでこそ成長するんですが。TechFirm Android Labさん、貴重な情報をありがとうございました!