概要
アプリケーションのパフォーマンスに大きな影響を与えるため、大量の画像をロードする Android アプリケーションでは効果的なメモリ管理が重要です。
メモリ キャッシュとディスク キャッシュを組み合わせて画像をキャッシュすることにより、多数の画像が読み込まれる状況でアプリケーションのパフォーマンスを大幅に向上させることができます。
キャッシュの詳細については、このリソースを参照してください。
メモリ キャッシュ: デバイスの RAM メモリに画像をキャッシュします。
ディスク キャッシュ: RAM メモリのサイズはそれほど大きくないため、RAM のデータ キャッシュはすぐにいっぱいになります。 したがって、この場合はディスク キャッシュが使用され、メモリ キャッシュで利用できない画像の読み込み時間を短縮するのに役立ちます。
課題
クラウド内のギャラリーには、平均サイズが1.5 MB、合計サイズが6 GBの4000枚の画像が含まれていますが、デバイスには使用可能なRAMが150 MBしかありません。
質問: すべての画像をスムーズに表示するにはどうすればよいですか?
Android開発をする時に画像の取得に抱えた問題
画像キャッシュのライブラリーを使用することにした
DisplayingBitmaps ライブラリについて学ぶ
Github: android-DisplayingBitmaps
イメージキャッシュ
一度アクセスした画像をキャッシュに保管し、次回より同じ画像にアクセスした際の表示を速くする仕組みです。
基本キャッシュの仕組み
画像キャッシュのライブラリーに主なコンポーネントは次の通りです。
イメージフェッチャー
画像フェッチャーは次のように機能します。
一般的な画像キャッシュ戦略:
LRU(最長時間未使用)は最も一般的なキャッシュ戦略
LRUアルゴリズム
キャッシュメモリがいっぱいになったとき、その中にあるデータのうち、未使用の時間が最も長いデータを捨てるというアルゴリズムです。
ディスクキャッシュ
SDCardなど外部メモリにDiskLruCacheのオブジェクトを初期します. メモリの容量をどのぐらい設定すべきか: 10MB?
private static final int DEFAULT_DISK_CACHE_SIZE = 1024 * 1024 * 10; // 10MB
public int diskCacheSize = DEFAULT_DISK_CACHE_SIZE;
if (getUsableSpace(diskCacheDir) > mCacheParams.diskCacheSize) {
try {
mDiskLruCache = DiskLruCache.open(
diskCacheDir, 1, 1, mCacheParams.diskCacheSize);
} catch (final IOException e) {
mCacheParams.diskCacheDir = null;
}
}
メモリキャッシュ
RAMに指定した容量でLruCacheのオブジェクトを初期します。最大使用可能VMメモリを基づいくメモリキャッシュのサイズを設定する: 25%?
private LruCache<String, BitmapDrawable> mMemoryCache;
// Set memory cache size is 25% of the max available VM memory
cacheParams.setMemCacheSizePercent(0.25f);
// Initialize memory cache
mMemoryCache = new LruCache<String, BitmapDrawable>(mCacheParams.memCacheSize);
画像の最適化
大きな画像をそのままにRAMメモリにロードすると効率化はあまり出ないので、小さいサイズに縮小し・RAMメモリにロードします。
たとえば、解像度が2048x1536の画像を4分の1に縮小すると、約512x384の画像が生成されます。 これをメモリにロードすると、イメージ全体で 12MBではなく0.75MBが使用されます。
画像キャッシュの仕組み詳細
注意点
キャッシュをメモリで保持しているので、画像が更新されていても保持しているキャッシュが優先的に表示され、新しい画像が表示されない場合があります。
解決策: