Android - как избежать перегрузки памяти с помощью растровых изображений? - PullRequest
3 голосов
/ 09 февраля 2011

Мое приложение использует растровые изображения, и каждый раз, когда пользователь приходит к определенной деятельности, где он показывает изображение во второй раз, когда перестает работать.

Bitmap bm = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory()+"//Pics/"Image.jpg");

Я пытался использовать такие вещи, как ...

BitmapFactory.Options options = new BitmapFactory.Options();
     options.inTempStorage = new byte[16*1024];

Не уверен, что настроить его тоже.Но это не помогает.Как только пользователь покидает это действие, нет ли способа очистить растровое изображение и т. Д.?спасибо

Ответы [ 3 ]

8 голосов
/ 09 февраля 2011

Помимо использования Bitmap.recycle () в соответствии с предложением (что не подходит для всех ситуаций, и боль в шее спрашивать: « мне все еще нужен этот растр? * "), Я всегда использую эту технику, которая работает очень хорошо:

// 1. create a cache map
private WeakHashMap<String, SoftReference<Bitmap>> mCache;

Как видите, это хеш-карта WeakReference с со значениями SoftReference.

//2. when you need a bitmap, ask for it:
public Bitmap get(String key){
    if( key == null ){
        return null;
    }
    if( mCache.containsKey(key) ){
        SoftReference<Bitmap> reference = mCache.get(key);
        Bitmap bitmap = reference.get();
        if( bitmap != null ){
            return bitmap;
        }
        return decodeFile(key);
    }
    // the key does not exists so it could be that the
    // file is not downloaded or decoded yet...
    File file = new File(Environment.getExternalStorageDirectory(), key);
    if( file.exists() ){
        return decodeFile(key);
    } else{
        throw new RuntimeException("Boooom!");
    }
}

Это проверит карту кеша. Если файл уже был декодирован, он будет возвращен; в противном случае он будет декодирован и кэширован.

//3. the decode file will look like this in your case
private Bitmap decodeFile(String key) {
    Bitmap bitmap = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory()+"//Pics/"+key);
    mCache.put(key, new SoftReference<Bitmap>(bitmap));
    return bitmap;
}

Работать с мягкими ссылками приятно, потому что вы переносите ответственность за удаление растровых изображений из памяти на ОС.

8 голосов
/ 09 февраля 2011

Вызов Bitmap.recycle () , когда вы закончили использовать растровое изображение для освобождения памяти.

1 голос
/ 13 марта 2012

Будьте в курсе. Когда мы думаем о программных ссылках, мы думаем, что ОС удалит объекты из программной ссылки из памяти перед тем, как сообщить об исключении вне памяти.

В андроиде это не всегда так. Мне пришлось реализовать собственную систему кэширования изображений, и я могу заверить, что объекты с мягкой ссылкой не были удалены из памяти, когда память была почти заполнена.

Наконец мне пришлось переключиться на жесткие ссылки (обычные), но я использовал android.support.v4.util.LruCache для управления кэшированными объектами. Я бы назвал recycle для обратного вызова onRemoved из кэша lru. Это определенно более удобно.

Приветствие.

...