android picasso 缓存目录,使用Picasso和自定义磁盘缓存

如何编写之前,Picasso使用底层Http客户端的缓存。

HttpUrlConnection的内置缓存无法在真正的离线模式下工作, 如果由于某些原因使用OkHttpClient是不可取的 ,则可以使用您自己的磁盘缓存实现(当然基于DiskLruCache )。

其中一种方法是将com.squareup.picasso.UrlConnectionDownloader和programm整个逻辑子类com.squareup.picasso.UrlConnectionDownloader :

@Override public Response load(final Uri uri, int networkPolicy) throws IOException { ... }

然后像这样使用你的实现:

new Picasso.Builder(context).downloader().build();

这是我的UrlConnectionDownloader实现,它与磁盘缓存一起使用,即使在完全脱机模式下也可以发送到Picasso位图:

public class PicassoBitmapDownloader extends UrlConnectionDownloader { private static final int MIN_DISK_CACHE_SIZE = 5 * 1024 * 1024; // 5MB private static final int MAX_DISK_CACHE_SIZE = 50 * 1024 * 1024; // 50MB @NonNull private Context context; @Nullable private DiskLruCache diskCache; public class IfModifiedResponse extends Response { private final String ifModifiedSinceDate; public IfModifiedResponse(InputStream stream, boolean loadedFromCache, long contentLength, String ifModifiedSinceDate) { super(stream, loadedFromCache, contentLength); this.ifModifiedSinceDate = ifModifiedSinceDate; } public String getIfModifiedSinceDate() { return ifModifiedSinceDate; } } public PicassoBitmapDownloader(@NonNull Context context) { super(context); this.context = context; } @Override public Response load(final Uri uri, int networkPolicy) throws IOException { final String key = getKey(uri); { Response cachedResponse = getCachedBitmap(key); if (cachedResponse != null) { return cachedResponse; } } IfModifiedResponse response = _load(uri); if (cacheBitmap(key, response.getInputStream(), response.getIfModifiedSinceDate())) { IfModifiedResponse cachedResponse = getCachedBitmap(key); if (cachedResponse != null) {return cachedResponse; } } return response; } @NonNull protected IfModifiedResponse _load(Uri uri) throws IOException { HttpURLConnection connection = openConnection(uri); int responseCode = connection.getResponseCode(); if (responseCode >= 300) { connection.disconnect(); throw new ResponseException(responseCode + " " + connection.getResponseMessage(), 0, responseCode); } long contentLength = connection.getHeaderFieldInt("Content-Length", -1); String lastModified = connection.getHeaderField(Constants.HEADER_LAST_MODIFIED); return new IfModifiedResponse(connection.getInputStream(), false, contentLength, lastModified); } @Override protected HttpURLConnection openConnection(Uri path) throws IOException { HttpURLConnection conn = super.openConnection(path); DiskLruCache diskCache = getDiskCache(); DiskLruCache.Snapshot snapshot = diskCache == null ? null : diskCache.get(getKey(path)); if (snapshot != null) { String ifModifiedSince = snapshot.getString(1); if (!isEmpty(ifModifiedSince)) { conn.addRequestProperty(Constants.HEADER_IF_MODIFIED_SINCE, ifModifiedSince); } } return conn; } @Override public void shutdown() { try { if (diskCache != null) { diskCache.flush(); diskCache.close(); } } catch (IOException e) { e.printStackTrace(); } super.shutdown(); } public boolean cacheBitmap(@Nullable String key, @Nullable InputStream inputStream, @Nullable String ifModifiedSince) { if (inputStream == null || isEmpty(key)) { return false; } OutputStream outputStream = null; DiskLruCache.Editor edit = null; try { DiskLruCache diskCache = getDiskCache(); edit = diskCache == null ? null : diskCache.edit(key); outputStream = edit == null ? null : new BufferedOutputStream(edit.newOutputStream(0)); if (outputStream == null) { return false; } ChatUtils.copy(inputStream, outputStream); outputStream.flush(); edit.set(1, ifModifiedSince == null ? "" : ifModifiedSince); edit.commit(); return true; } catch (Exception e) { e.printStackTrace(); } finally { if (edit != null) { edit.abortUnlessCommitted(); } ChatUtils.closeQuietly(outputStream); } return false; } @Nullable public IfModifiedResponse getCachedBitmap(String key) { try { DiskLruCache diskCache = getDiskCache(); DiskLruCache.Snapshot snapshot = diskCache == null ? null : diskCache.get(key); InputStream inputStream = snapshot == null ? null : snapshot.getInputStream(0); if (inputStream == null) { return null; } return new IfModifiedResponse(inputStream, true, snapshot.getLength(0), snapshot.getString(1)); } catch (Exception e) { e.printStackTrace(); } return null; } @Nullable synchronized public DiskLruCache getDiskCache() { if (diskCache == null) { try { File file = new File(context.getCacheDir() + "/images"); if (!file.exists()) { //noinspection ResultOfMethodCallIgnored file.mkdirs(); } long maxSize = calculateDiskCacheSize(file); diskCache = DiskLruCache.open(file, BuildConfig.VERSION_CODE, 2, maxSize); } catch (Exception e) { e.printStackTrace(); } } return diskCache; } @NonNull private String getKey(@NonNull Uri uri) { String key = md5(uri.toString()); return isEmpty(key) ? String.valueOf(uri.hashCode()) : key; } @Nullable public static String md5(final String toEncrypt) { try { final MessageDigest digest = MessageDigest.getInstance("md5"); digest.update(toEncrypt.getBytes()); final byte[] bytes = digest.digest(); final StringBuilder sb = new StringBuilder(); for (byte aByte : bytes) { sb.append(String.format("%02X", aByte)); } return sb.toString().toLowerCase(); } catch (Exception e) { e.printStackTrace(); return null; } } static long calculateDiskCacheSize(File dir) { long available = ChatUtils.bytesAvailable(dir); // Target 2% of the total space. long size = available / 50; // Bound inside min/max size for disk cache. return Math.max(Math.min(size, MAX_DISK_CACHE_SIZE), MIN_DISK_CACHE_SIZE); } }

PicassoAndroid系统的图片下载缓存类库 Picasso 是Square开源的一个用于Android系统下载缓存图片的项目。该项目其他一些下载图片项目的主要区别之一是:使用4.0+系统上的HTTP缓存来代替磁盘缓存Picasso使用是非常简单的,例如: 帮助 1 Picasso.with(context).load("http://i.imgur.com/DvpvklR.png.into(imageView")); Picasso有如下特性: 处理Adapter中的 ImageView 回收取消已经回收ImageView的下载进程 使用最少的内存完成复杂的图片转换,比如把下载的图片转换为圆角等 自动添加磁盘内存缓存 具体介绍 在Adapter中下载 自动检测Adapter中的ImageView重用取消不必要的下载 帮助 01.@Override public void getView(int position, View convertView, ViewGroup parent) { 02.SquaredImageView view = (SquaredImageView) convertView; 03.if (view == null) { 04.view = new SquaredImageView(context); 05.} 06.String url = getItem(position);Picasso.with(context).load(url).into(view); 07.} 复制代码 图片转换 转换图片以适合所显示的ImageView,来减少内存消耗 帮助 01.Picasso.with(context) 02..load(url) 03..resize(50, 50) 04..centerCrop() 05..into(imageView) 复制代码 还可以设置自定义转换来实现高级效果,例如下面的矩形特效(把图片居中裁剪为矩形) 帮助 01.public class CropSquareTransformation implements Transformation { 02.@Override public Bitmap transform(Bitmap source) { 03.int size = Math.min(source.getWidth(), source.getHeight()); 04.int x = (source.getWidth() - size) / 2; 05.int y = (source.getHeight() - size) / 2; 06.Bitmap result = Bitmap.createBitmap(source, x, y, size, size); 07.if (result != source) { 08.source.recycle(); 09.} 10.return result; 11.}@Override public String key() { return "square()"; } 12.} 复制代码 用该类示例调用函数 RequestBuilder.transform(Transformation) 即可。 占位符图片 Picasso支持下载加载错误占位符图片。 帮助 Picasso.with(context) .load(url) .placeholder(R.drawable.user_placeholder) .error(R.drawable.user_placeholder_error) .into(imageView); 如果重试3次(下载源代码可以根据需要修改)还是无法成功加载图片 则用错误占位符图片显示。 支持本地资源加载 从 Resources, assets, files, content providers 加载图片都支持 Picasso.with(context).load(R.drawable.landing_screen).into(imageView1); Picasso.with(context).load(new File("/images/oprah_bees.gif")).into(imageView2); 调试支持 调用函数 Picasso.setDebug(true) 可以在加载的图片左上角显示一个 三角形 ,不同的颜色代表加载的来源 红色:代表从网络下载的图片 黄色:代表从磁盘缓存加载的图片 绿色:代表从内存中加载的图片 如果项目中使用了OkHttp库的话,默认会使用OkHttp来下载图片。否则使用HttpUrlConnection来下载图片
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值