Форум программистов, компьютерный форум CyberForum.ru

Программирование Android

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 12, средняя оценка - 5.00
Stylish2013
7 / 7 / 1
Регистрация: 20.04.2013
Сообщений: 666
#1

Показывать изображения, если они есть в Кэше - Android

26.06.2013, 21:15. Просмотров 1569. Ответов 4
Метки нет (Все метки)

Использую ImageLoader, загружаю изображения из интернета. Когда есть интернет он загружает изображения и кеширует т.е. при последующем запуске без интернета изображения отображаются, но когда есть интернет он начинает грузить картинки заново, как сделать чтобы если картинки есть в кэше просто их показать.

код:

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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
public class ImageLoader {
 
    
    MemoryCache memoryCache=new MemoryCache();
    FileCache fileCache;
    private Map<ImageView, String> imageViews=Collections.synchronizedMap(new WeakHashMap<ImageView, String>());
    ExecutorService executorService; 
    
    public ImageLoader(Context context){
        fileCache=new FileCache(context);
        executorService=Executors.newFixedThreadPool(5);
    }
    
    final int st = R.drawable.not;
    public void DisplayImage(String url, ImageView imageView)
    {
        imageViews.put(imageView, url);
        Bitmap bitmap=memoryCache.get(url);
        if(bitmap!=null)
            imageView.setImageBitmap(bitmap);
        else
        {
            queuePhoto(url, imageView);
            imageView.setImageResource(st);
            
        }
    }
        
    private void queuePhoto(String url, ImageView imageView)
    {
        PhotoToLoad p=new PhotoToLoad(url, imageView);
        executorService.submit(new PhotosLoader(p));
    }
    
    private Bitmap getBitmap(String url) 
    {
        File f=fileCache.getFile(url);
        
        //from SD cache
        Bitmap b = decodeFile(f);
        if(b!=null)
            return b;
        
        //from web
        try {
            Bitmap bitmap=null;
            URL imageUrl = new URL(url);
            HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection();
            conn.setConnectTimeout(30000);
            conn.setReadTimeout(30000);
            conn.setInstanceFollowRedirects(true);
            InputStream is=conn.getInputStream();
            OutputStream os = new FileOutputStream(f);
            Utils.CopyStream(is, os);
            os.close();
            bitmap = decodeFile(f);
            return bitmap;
        } catch (Exception ex){
           ex.printStackTrace();
           return null;
        }
    }
 
    //decodes image and scales it to reduce memory consumption
    private Bitmap decodeFile(File f){
        try {
            //decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(new FileInputStream(f),null,o);
            
            //Find the correct scale value. It should be the power of 2.
            final int REQUIRED_SIZE = 70; //standart
 
            int width_tmp=o.outWidth, height_tmp=o.outHeight;
            int scale=1;
            while(true){
                if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE)
                    break;
                width_tmp/=2;
                height_tmp/=2;
                scale*=2;
            }
            
            //decode with inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize=scale;
            return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
        } catch (FileNotFoundException e) {}
        return null;
    }
    
    //Task for the queue
    private class PhotoToLoad
    {
        public String url;
        public ImageView imageView;
        public PhotoToLoad(String u, ImageView i){
            url=u; 
            imageView=i;
        }
    }
    
    class PhotosLoader implements Runnable {
        PhotoToLoad photoToLoad;
        PhotosLoader(PhotoToLoad photoToLoad){
            this.photoToLoad=photoToLoad;
        }
        
        @Override
        public void run() {
            if(imageViewReused(photoToLoad))
                return;
            Bitmap bmp=getBitmap(photoToLoad.url);
            memoryCache.put(photoToLoad.url, bmp);
            if(imageViewReused(photoToLoad))
                return;
            BitmapDisplayer bd=new BitmapDisplayer(bmp, photoToLoad);
            Activity a=(Activity)photoToLoad.imageView.getContext();
            a.runOnUiThread(bd);
        }
    }
    
    boolean imageViewReused(PhotoToLoad photoToLoad){
        String tag=imageViews.get(photoToLoad.imageView);
        if(tag==null || !tag.equals(photoToLoad.url))
            return true;
        return false;
    }
    
    //Used to display bitmap in the UI thread
    class BitmapDisplayer implements Runnable
    {
        Bitmap bitmap;
        PhotoToLoad photoToLoad;
        public BitmapDisplayer(Bitmap b, PhotoToLoad p){bitmap=b;photoToLoad=p;}
        public void run()
        {
            if(imageViewReused(photoToLoad))
                return;
            if(bitmap!=null)
                photoToLoad.imageView.setImageBitmap(bitmap);
            else
                  photoToLoad.imageView.setImageResource(st);
        
        
        }
    }
 
    public void clearCache() {
        memoryCache.clear();
        fileCache.clear();
    }
    
 
}
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
public class FileCache {
    
    private File cacheDir;
    
    public FileCache(Context context){
        //Find the dir to save cached images
        if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
            cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"LazyList");
        else
            cacheDir=context.getCacheDir();
        if(!cacheDir.exists())
            cacheDir.mkdirs();
    }
    
    public File getFile(String url){
        //I identify images by hashcode. Not a perfect solution, good for the demo.
        String filename=String.valueOf(url.hashCode());
        //Another possible solution (thanks to grantland)
        //String filename = URLEncoder.encode(url);
        File f = new File(cacheDir, filename);
        return f;
        
    }
    
    public void clear(){
        File[] files=cacheDir.listFiles();
        if(files==null)
            return;
        for(File f:files)
            f.delete();
    }
 
}
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class MemoryCache {
    private Map<String, SoftReference<Bitmap>> cache=Collections.synchronizedMap(new HashMap<String, SoftReference<Bitmap>>());
    
    public Bitmap get(String id){
        if(!cache.containsKey(id))
            return null;
        SoftReference<Bitmap> ref=cache.get(id);
        return ref.get();
    }
    
    public void put(String id, Bitmap bitmap){
        cache.put(id, new SoftReference<Bitmap>(bitmap));
    }
 
    public void clear() {
        cache.clear();
    }
}
Добавлено через 7 часов 8 минут
может дополнительная информация нужна?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.06.2013, 21:15     Показывать изображения, если они есть в Кэше
Посмотрите здесь:

Android Как узнать есть ли фронтальная камера на устройстве и если есть, то использовать ее?
Как заставить ListView показывать ограниченное количество элементов? Android
Android База записей, из которой каждый день нужно брать пару-тройку определенных и показывать на экране
Android Увеличение изображения
Как сохранить целочисленную переменную в кэше? Android
ActionBar, всегда показывать троеточие Android
Увеличение изображения Android
Android Вращение изображения
Android Загрузка изображения
Android SQLite запретить удаление строки, если есть ссылки на нее
Как при повороте экрана показывать видео дальше, а не сначала Android
Android Показывать или скрывать записи в адаптере

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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
lavan
51 / 51 / 1
Регистрация: 21.03.2009
Сообщений: 371
28.06.2013, 11:57     Показывать изображения, если они есть в Кэше #2
код,я не смотрел. мне кажется нет другого варианта кроме как перед загрузкой фото пройтись по кэшу и проверить на наличие этого фото в кэше
Stylish2013
7 / 7 / 1
Регистрация: 20.04.2013
Сообщений: 666
30.06.2013, 17:48  [ТС]     Показывать изображения, если они есть в Кэше #3
Цитата Сообщение от lavan Посмотреть сообщение
пройтись по кэшу и проверить на наличие этого фото в кэше
да я тоже так подумал, но вот как это сделать не знаю.. В первом посте есть код кэша. Подскажите пожалуйста как проверить?
lavan
51 / 51 / 1
Регистрация: 21.03.2009
Сообщений: 371
30.06.2013, 21:34     Показывать изображения, если они есть в Кэше #4
раз фото было загр. через инет,значит у вас есть её url который будет ключом в map,а дальше сопоставляйте новое url с теми,что уже в map
MonStar
19 / 19 / 3
Регистрация: 10.04.2011
Сообщений: 225
01.07.2013, 20:33     Показывать изображения, если они есть в Кэше #5
Вот моя реализация ImageLoader. Изображения кешируются в памяти и в кэш директорию телефона. Надеюсь разберетесь, если есть вопросы по возможности отвечу.

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

У меня объект класса предоставляется классом Application, точнее его наследником. Можно немного переписать под обычный паттерн синглтон.

Кликните здесь для просмотра всего текста
Java
1
2
3
4
5
6
import android.widget.ImageView;
 
public interface IImageManager {
 
    public void loadImage(String url, ImageView imageView);
}
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
 
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.support.v4.util.LruCache;
import android.util.Log;
import android.util.SparseArray;
import android.widget.ImageView;
 
public abstract class AbstractImageManager implements IImageManager{
    
    public static final String TAG = AbstractImageManager.class.getSimpleName();
 
    private LruCache<String, Bitmap> memoryCache;
    private SparseArray<String> syncImageView;
    private Handler handler;
    private ExecutorService executorService;
    private Exception mError;
    private List<Callback> queue;
    private Context context;
 
    public interface Callback {
        String getUrl();
 
        void onSuccess(Bitmap bm);
 
        void onError(Exception e);
    }
    
    public AbstractImageManager(Context context, int sizeMemoryCache, int poolSize) {
        this.context = context;
        memoryCache = new LruCache<String, Bitmap>(sizeMemoryCache) {
            @Override
            protected int sizeOf(String key, Bitmap value) {
                int size = value.getWidth() * value.getHeight() * 4;
                return size;
            }
 
        };
        syncImageView = new SparseArray<String>();
        handler = new Handler();
        queue = Collections.synchronizedList(new ArrayList<Callback>());
        executorService = Executors.newFixedThreadPool(poolSize);
    }
    
    public void loadImage(final String url, final ImageView imageView) {
        if (url == null || url.equals("") || imageView == null) {
            return;
        }
        Bitmap bitmap = getBitmapFromMemory(url);
        if (bitmap != null) {
            imageView.setImageBitmap(bitmap);
            return;
        } else {
            imageView.setImageDrawable(null);
        }
 
        syncImageView.put(imageView.hashCode(), url);
 
        queue.add(0, new Callback() {
 
            @Override
            public void onSuccess(Bitmap bm) {
                if (mError != null) {
                    onError(mError);
                    mError = null;
                    return;
                }
                if (bm != null) {
                    if (getUrl().equals(syncImageView.get(imageView.hashCode()))) {
                        imageView.setImageBitmap(bm);
                        syncImageView.delete(imageView.hashCode());
                    }
                    addBitmapToMemCache(getUrl(), bm);
                }
                execute();
            }
 
            @Override
            public void onError(Exception e) {
                Log.e(TAG, "Error: " + e);
            }
 
            @Override
            public String getUrl() {
                return url;
            }
        });
        execute();
    }
 
    private void execute() {
        executorService.execute(new Runnable() {
            @Override
            public void run() {
 
                final Callback callback;
 
                synchronized (queue) {
                    if (queue.isEmpty()) {
                        return;
                    }
                    callback = queue.remove(0);
                }
 
                Bitmap bitmap = null;
                String url = callback.getUrl();
                String path = getPathCacheDir(url);
                if (new File(path).exists()) {
                    bitmap = loadBitmapFromFile(path);
                } else {
                    try {
                        bitmap = loadBitmapFromWeb(url);
                    } catch (final IOException e) {
                        mError = e;
                    }
                }
 
                final Bitmap bm = bitmap;
                handler.post(new Runnable() {
 
                    @Override
                    public void run() {
                        callback.onSuccess(bm);
                    }
                });
            }
        });
    }
 
    private Bitmap getBitmapFromMemory(String url) {
        return memoryCache.get(url);
    }
 
    private void addBitmapToMemCache(String url, Bitmap bitmap) {
        if (getBitmapFromMemory(url) == null) {
            memoryCache.put(url, bitmap);
        }
    }
    
    private Bitmap loadBitmapFromFile(String path) {
        return BitmapFactory.decodeFile(path);
    }
 
    private Bitmap loadBitmapFromWeb(final String url) throws IOException {
        final Bitmap bitmap = loadBitmap(url);
        new Thread(new Runnable() {
 
            @Override
            public void run() {
                addBitmapToFileCache(getPathCacheDir(url), bitmap);
            }
        }).start();
        return bitmap;
    }
 
 
    private void addBitmapToFileCache(String path, Bitmap bitmap) {
        if (bitmap == null || path == null) {
            Log.d(TAG, "Write to file bitmap or path = null ");
            return;
        }
        OutputStream out = null;
        try {
            out = new BufferedOutputStream(new FileOutputStream(path));
            bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
        } catch (FileNotFoundException e) {
            this.mError = e;
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    this.mError = e;
                }
            }
        }
    }
 
    protected Context getContext() {
        return context;
    }
    
    protected abstract Bitmap loadBitmap(String url) throws IOException;
 
    protected abstract String getPathCacheDir(String url);
}
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
import java.io.File;
import java.io.IOException;
 
import android.content.Context;
import android.graphics.Bitmap;
 
import common.managers.AbstractImageManager;
import common.utils.MD5Util;
 
public class ImageManager extends AbstractImageManager {
 
    public static final String TAG = ImageManager.class.getSimpleName();
    public static final String SERVICE_NAME = "--IMAGE_MANAGER--";
 
    private static final int SIZE_MEM_CACHE = 4 * 1024 * 1024;
    private static final int POOL_SIZE = 3;
 
    public ImageManager(Context context) {
        super(context, SIZE_MEM_CACHE, POOL_SIZE);
    }
 
    public static ImageManager get(Context context) {
        return (ImageManager) context.getApplicationContext().getSystemService(SERVICE_NAME);
    }
 
    @Override
    public Bitmap loadBitmap(String url) throws IOException {
        return HttpClientManager.get(getContext()).loadAsBitmap(url);
    }
 
    @Override
    public String getPathCacheDir(String url) {
        return getContext().getCacheDir().getAbsolutePath() + File.separator + MD5Util.getInstance().md5(url);
    }
 
}
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
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
 
public class MD5Util {
 
    private static final MD5Util INSTANCE = new MD5Util();
    
    public static MD5Util getInstance(){
        return INSTANCE;
    }
    
     public String md5(String s) {
            try {
                MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
                digest.update(s.getBytes());
                byte messageDigest[] = digest.digest();
                StringBuffer hexString = new StringBuffer();
                for (int i = 0; i < messageDigest.length; i++) {
                    hexString.append(Integer.toHexString(0xFF & messageDigest[i]));
                }
                return hexString.toString();
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
            return "";
        }
}
Yandex
Объявления
01.07.2013, 20:33     Показывать изображения, если они есть в Кэше
Ответ Создать тему
Опции темы

Текущее время: 09:52. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru