画像のキャッシュは、私が作成してアプリストアに配置したアプリの重要な部分でした。アプリは、画像をダウンロードしてメモリとSDカードの両方にキャッシュし、その範囲が1回の実行を超えて拡張されるようにする必要があります。
一般的な考え方は、a)メタデータに基づくキーを介して画像を連想コンテナ(HashMap)に保存し、b)画像ファイルをSDCardに書き込むCachingManagerに画像を追加することでした。
メモリ不足の状態では、HashMapを解放します。それでも、画像はSD_Cardから取得して、もう一度メモリにキャッシュすることができます。
リサイクルせずにこれを行うことができましたが、それでもメモリの問題は見られません。私が理解しているように、リサイクルは必要ありませんが、ジンジャーブレッド以前のOSではビットマップの割り当てがネイティブメモリを使用するため、「ビットマップ」に使用されるメモリの以前のリリースを取得するのに役立ちます。つまり、Dalvikヒープの一部ではないメモリ。したがって、ガベージコレクタはこのメモリを解放せず、実装固有のポリシーによって解放されます。
これは、Cache_Managerクラスからのものです。
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);
}
}
}
//これがFile_ManagerクラスのwriteImage()の例です
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;
}
}