图像缓存是我构建并放入应用商店的应用程序的重要组成部分。该应用程序需要下载图像并将它们缓存在内存和 SDCard 上,以便它们的范围超出单次运行。
总体思路是将图像添加到缓存管理器中,a) 通过基于元数据的键将图像存储在关联容器 (HashMap) 中,以及 b) 将图像文件写入 SDCard。
在内存不足的情况下,我释放 HashMap。然而,仍然可以从 SD_Card 中检索图像并再次缓存到内存中。
我能够在不回收的情况下做到这一点,并且仍然没有看到内存问题。据我了解,回收不是必需的,但有助于获得用于“位图”的更早版本的内存,因为在 Gingerbread 之前的操作系统中,位图的分配使用本机内存。即不属于 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;
}
}