Кэширование изображений было важной частью приложения, которое я создал и поместил в магазин приложений. Приложение должно загружать изображения и кэшировать их как в памяти, так и на SDCard, чтобы их область действия выходила за рамки одного запуска.
Общая идея состояла в том, чтобы добавить изображения в Caching Manager, который а) сохраняет изображение в ассоциативном контейнере (HashMap), используя ключ на основе метаданных, и б) записывает файл изображения на SDCard. ,
При нехватке памяти я выпускаю HashMap. Тем не менее, изображения все еще могут быть извлечены из SD_Card и снова кэшироваться в память.
Я смог сделать это без переработки и до сих пор не вижу проблем с памятью. Насколько я понимаю, переработка не является необходимой, но помогает получить более ранний выпуск памяти, используемой для «растровых изображений», из-за того, что при выделении для растровых изображений в пред-Gingerbread-ОС используется Native Memory. то есть память, которая не является частью кучи Далвика. Таким образом, сборщик мусора не освобождает эту память, а освобождается политиками, специфичными для реализации.
Это из класса 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);
}
}
}
// Вот пример writeImage () из класса File_Manager
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;
}
}