Форум программистов, компьютерный форум, киберфорум
Наши страницы
Программирование Android
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/9: Рейтинг темы: голосов - 9, средняя оценка - 5.00
max_max
5 / 5 / 1
Регистрация: 12.08.2014
Сообщений: 26
1

Создание кэша изображений

15.08.2014, 18:28. Просмотров 1627. Ответов 10
Метки нет (Все метки)

Нужна помощь в создании в приложении кэша для изображений типа DiscLruCache
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.08.2014, 18:28
Ответы с готовыми решениями:

Очистка кэша
Добрый вечер! Я пишу под андроид на C# в Xamarin. Возникла такая проблема: в...

Узнать объём кэша выделенный приложению
Всем привет! Кто знает как узнать объём кэша который выделен приложению...

Загрузка картинок Picasso из дискового кэша, когда нет интернета
Подскажите как можно при помощи Picasso реализовать загрузку картинок в фон...

Создать базу данных с(Создание функции БД, Создание процедуры БД, Создание тригера БД)
В задание для курсовой работы по БД входят вот такие пункты: 1.2 Создание...

Создание изображений
Примерно этого я хочу добиться, только с помощью php, JavaScript......

10
646kapeh064
59 / 58 / 16
Регистрация: 09.12.2013
Сообщений: 208
15.08.2014, 18:45 2
Недавно делал класс
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import android.content.Context;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
 
/**
 * Created by Karen on 14.08.2014.
 */
public class CacheManager {
    private long maxCacheSize;
    private File cacheDir;
 
    public CacheManager(Context context, String subDir) {
        this(context, subDir, 52428800L); // Max dir size 50MB
    }
 
    public CacheManager(Context context, String subDir, long maxCacheSize) {
        this.maxCacheSize = maxCacheSize;
        this.cacheDir = new File(context.getCacheDir(), subDir);
        if (!this.cacheDir.exists()) {
              this.cacheDir.mkdirs();
        }
    }
 
    public void cacheData(byte[] data, String name) throws IOException {
        long size = getCacheSize();
        long newSize = data.length + size;
 
        if (newSize > maxCacheSize) {
            cleanCache(newSize - maxCacheSize);
        }
 
        File file = new File(cacheDir, name);
        FileOutputStream os = new FileOutputStream(file);
        try {
            os.write(data);
        } finally {
            os.flush();
            os.close();
        }
    }
 
    public byte[] retrieveData(String name) throws IOException {
        File file = new File(cacheDir, name);
 
        if (!file.exists()) {
            // Data doesn't exist
            return null;
        }
 
        byte[] data = new byte[(int) file.length()];
        FileInputStream is = new FileInputStream(file);
        try {
            is.read(data);
        } finally {
            is.close();
        }
 
        return data;
    }
 
    private void cleanCache(long bytes) {
        long bytesDeleted = 0;
        File[] files = cacheDir.listFiles();
 
        for (File file : files) {
            bytesDeleted += file.length();
            file.delete();
 
            if (bytesDeleted >= bytes) {
                break;
            }
        }
    }
 
    private long getCacheSize() {
        long size = 0;
        File[] files = cacheDir.listFiles();
 
        for (File file : files) {
            if (file.isFile()) {
                size += file.length();
            }
        }
 
        return size;
    }
}
Создает в папке для кеша

Использование:
Java
1
CacheManager cacheManager = new CacheManager(context, "img");
Тебе остается только сохранять картинку в массив байт и обратно.
0
KillAndEat
63 / 63 / 8
Регистрация: 17.05.2013
Сообщений: 286
15.08.2014, 23:05 3
https://github.com/thest1/LazyList/b...moryCache.java
0
max_max
5 / 5 / 1
Регистрация: 12.08.2014
Сообщений: 26
17.08.2014, 18:48  [ТС] 4
646kapeh064, большое спасибо! Работает.
0
max_max
5 / 5 / 1
Регистрация: 12.08.2014
Сообщений: 26
18.08.2014, 19:10  [ТС] 5
646kapeh064, все хорошо, только после некоторого времени перелистывания картинок выводит java.lang.OutOfMemoryError, ошибку даёт в методе retreiveData, в строчке
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
В логах после перелистывания (например):
GC_FOR_ALLOC freed 4465K, 23% free 19969K/25928K, ..
Grow heap (frag case) to 27.083MB for 3622416-byte allocation
И так пока хип не переполнит.
Может быть, кто сталкивался с такой проблемой.
0
646kapeh064
59 / 58 / 16
Регистрация: 09.12.2013
Сообщений: 208
18.08.2014, 19:31 6
Лучший ответ Сообщение было отмечено max_max как решение

Решение

max_max, не знаю поможет тебе или нет. Но я недавно обновлял этот класс у себя в RSS читалке.

CacheManager
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import android.content.Context;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
 
/**
 * Created by Karen on 14.08.2014.
 */
public class CacheManager {
    private long maxCacheSize;
    private File cacheDir;
 
    public CacheManager(Context context, String subDir) {
        this(context, subDir, 52428800L); // Max dir size 50MB
    }
 
    public CacheManager(Context context, String subDir, long maxCacheSize) {
        this.maxCacheSize = maxCacheSize;
        this.cacheDir = new File(context.getCacheDir(), subDir);
        if (!this.cacheDir.exists()) {
            this.cacheDir.mkdirs();
        }
    }
 
    public File getFile(String fileName) {
        return new File(cacheDir, fileName);
    }
 
    public void cacheData(byte[] data, String name) throws IOException {
        long size = getCacheSize();
        long newSize = data.length + size;
 
        if (newSize > maxCacheSize) {
            cleanCache(newSize - maxCacheSize);
        }
 
        File file = new File(cacheDir, name);
        FileOutputStream os = new FileOutputStream(file);
        try {
            os.write(data);
        } finally {
            os.flush();
            os.close();
        }
    }
 
    public OutputStream cacheDataStream(String name) throws FileNotFoundException {
        long size = getCacheSize();
 
        if (size > maxCacheSize) {
            cleanCache(size - maxCacheSize);
        }
 
        File file = new File(cacheDir, name);
        return new FileOutputStream(file);
    }
 
    public byte[] retrieveData(String name) throws IOException {
        File file = new File(cacheDir, name);
 
        if (!file.exists()) {
            return null;
        }
 
        byte[] data = new byte[(int) file.length()];
        FileInputStream is = new FileInputStream(file);
        try {
            is.read(data);
        } finally {
            is.close();
        }
 
        return data;
    }
 
    public InputStream retrieveDataStream(String name) throws FileNotFoundException {
        File file = new File(cacheDir, name);
 
        if (!file.exists()) {
            return null;
        }
 
        return new FileInputStream(file);
    }
 
    private void cleanCache(long bytes) {
        long bytesDeleted = 0;
        File[] files = cacheDir.listFiles();
 
        for (File file : files) {
            bytesDeleted += file.length();
            file.delete();
 
            if (bytesDeleted >= bytes) {
                break;
            }
        }
    }
 
    private long getCacheSize() {
        long size = 0;
        File[] files = cacheDir.listFiles();
 
        for (File file : files) {
            if (file.isFile()) {
                size += file.length();
            }
        }
 
        return size;
    }
}
CachedDrawable
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.Base64;
 
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
 
/**
 * Created by Karen on 14.08.2014.
 */
public class CachedDrawable {
    Context context;
    CacheManager cacheManager;
 
    public CachedDrawable(Context context) {
        this.context = context;
        this.cacheManager = new CacheManager(context, "img");
    }
 
    public boolean inCache(String url) throws UnsupportedEncodingException {
        String urlBase64 = getBase64(url);
        return cacheManager.getFile(urlBase64).exists();
    }
 
    public void save(String url, Drawable drawable) throws IOException {
        String urlBase64 = getBase64(url);
        Bitmap bitmap = drawableToBitmap(drawable);
        OutputStream stream = cacheManager.cacheDataStream(urlBase64);
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
        stream.close();
    }
 
    public Drawable load(String url) throws IOException {
        String urlBase64 = getBase64(url);
        InputStream stream = cacheManager.retrieveDataStream(urlBase64);
        if (stream == null) {
            return null;
        }
        Drawable drawable = BitmapDrawable.createFromStream(stream, null);
        drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
        return drawable;
    }
 
    private String getBase64(String fileName) throws UnsupportedEncodingException {
        return Base64.encodeToString(fileName.getBytes("UTF-8"),
               Base64.URL_SAFE | Base64.NO_WRAP);
    }
 
    private Bitmap drawableToBitmap(Drawable drawable) {
        if (drawable instanceof BitmapDrawable) {
            return ((BitmapDrawable)drawable).getBitmap();
        }
 
        Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
        drawable.draw(canvas);
 
        return bitmap;
    }
}
В класс CacheManager я добавил методы cacheDataStream и retrieveDataStream для работы с потоком, ну и метод getFile (например, чтоб проверять файл в кеше, есть ли он там).

В методы save и load класса CachedDrawable, передается параметр String url (ссылка на картинку в интернете, в моем случае), которая конвертируется в Base64 и полученная строка является именем файла в моем кеше. Ты можешь не изменять эту часть, просто имена файлов будут не в явном виде, а в Base64.
Внутри этих методов используются вышеупомянутые cacheDataStream и retrieveDataStream, так как я сразу решил, что все-таки передавать картинки массивом байт это плохо.

Ну и использование:
Java
1
2
3
4
5
Drawable drawable = cachedDrawable.load("my_any_text_or_url"); // Вернет картинку из кеша
. . .
cachedDrawable.save("my_any_text_or_url", drawable); // Сохранит drawable в кеш
. . .
boolean inCache = cachedDrawable.inCache("my_any_text_or_url"); // Вернет true если есть в кеше, иначе вернет false
Если вдруг сможешь это под себя подстроить, то думаю проблема пропадет.
1
max_max
5 / 5 / 1
Регистрация: 12.08.2014
Сообщений: 26
19.08.2014, 19:19  [ТС] 7
646kapeh064, спасибо, ошибка была не из-за этого, кстати, подогнал), работает.
0
646kapeh064
59 / 58 / 16
Регистрация: 09.12.2013
Сообщений: 208
19.08.2014, 19:25 8
Цитата Сообщение от max_max Посмотреть сообщение
ошибка была не из-за этого
А из-за чего?
0
max_max
5 / 5 / 1
Регистрация: 12.08.2014
Сообщений: 26
19.08.2014, 21:37  [ТС] 9
Кажется просто обнуление экзекуторов от асинктаска при перелистывании помогло, + recycle битмапа
0
yura91
1 / 25 / 2
Регистрация: 23.10.2013
Сообщений: 2,327
23.08.2014, 15:20 10
насколько я понял здесь класс который создает файл и сохраняет туда байты верно?

Добавлено через 4 минуты
а почему называется КЭШ ?? Тут вроде я посмотрел по методам создается файл и пишутся туда байты изображения??
0
YuraAAA
1578 / 1319 / 282
Регистрация: 25.10.2009
Сообщений: 3,436
Записей в блоге: 2
23.08.2014, 15:30 11
yura91, max_max, https://github.com/nostra13/Android-Universal-Image-Loader
0
23.08.2014, 15:30
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.08.2014, 15:30

Создание изображений
Помогите пожалуйста решить задачи по php, завтра екзамен!!!(наброски,...

Создание изображений по параметрам
Создание изображения наподобие информера погоды. Подскажите, как можно...

Создание галлереи изображений
Подскажите, как создать небольшую галерею изображений, которая будет...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru