本篇就来讲一讲Android的图片的处理,在Android App上加载图片是很常见的,同时也是很容易造成OOM。
如果你对加载大图、图片缓存、OOM异常等问题不太了解,请先看看郭大神这篇文章
Android高效加载大图、多图解决方案,有效避免程序OOM,分析的很详细;
当然,本篇主要是让你学会使用Picasso和Fresco这两个图片处理库,这两个库的使用方法在网上都很多,而且都非常简单,但是今天我会说点不一样的!
Picasso2 && OkHttp3
我在 第六篇 网络请求篇(上) 的时候为了说OkHttp3,就示例使用OkHttp3加载图片,其实那不是很好的加载图片的方法,Square有一款专门的图片加载工具Picasso:官网地址
Picasso的常规使用
在官网上可以看到,Picasso的使用方法很简单:
Picasso.with(context).load("path").into(imageView);
通过官网上面的解析,我们还可以了解到Picasso的其它的一些用法,比如:placeholder()、resize()、centerCrop()、error()等等;都可以很简单的实现。
同时,Picasso的内部会默认帮你实现了内存缓存,其大小为内存1/7左右,所以不做详述。因为今天我们要说的是本地缓存,如何用OkHttp3配合Picasso实现本地缓存呢?
Picasso的本地缓存
由于Picasso和OkHttp同属Square公司,所以,他们互相支持调用;
我在写这篇博客之前在google了很久,stackOverflow上面的用OkHttp写缓存都比较简单,也没有比较权威的说法。于是在github上面找到了Jake Wharton大神写的关于Picasso使用OkHttp3的配置,瞬间觉得这就是权威!看源码:
这里不把全部代码贴出来,部分解析:大家需要明确一点Downloader已经实现了DiskLruCache,我们现在需要的是配合OkHttp的网络请求来重写缓存。
public final class OkHttp3Downloader implements Downloader {
private static final String PICASSO_CACHE = "picasso-cache";
private static final int MIN_DISK_CACHE_SIZE = 5 * 1024 * 1024; // 5MB
private static final int MAX_DISK_CACHE_SIZE = 50 * 1024 * 1024; // 50MB
//新建一个默认的缓存文件夹
//可以在你手机中/android/data/yourapp/picasso-cache文件夹中可以找到
private static File createDefaultCacheDir(Context context) {
File cache = new
File(context.getApplicationContext().getCacheDir(), PICASSO_CACHE);
if (!cache.exists()) {
//noinspection ResultOfMethodCallIgnored
cache.mkdirs();
}
return cache;
}
//计算缓存文件的大小,
private static long calculateDiskCacheSize(File dir) {
long size = MIN_DISK_CACHE_SIZE;
try {
StatFs statFs = new StatFs(dir.getAbsolutePath());
long available = ((long) statFs.getBlockCount()) * statFs.getBlockSize();
// Target 2% of the total space.
size = available / 50;
} catch (IllegalArgumentException ignored) {}
// Bound inside min/max size for disk cache.
return Math.max(Math.min(size, MAX_DISK_CACHE_SIZE), MIN_DISK_CACHE_SIZE);
}
......
//网络请求时的本地缓存处理,如何没有网络且有缓存,则从缓存中读取;
@Override public Response load(Uri uri, int networkPolicy) throws IOException {
CacheControl cacheControl = null;
if (networkPolicy != 0) {
if (NetworkPolicy.isOfflineOnly(networkPolicy)) {
cacheControl = CacheControl.FORCE_CACHE;
} else {
CacheControl.Builder builder = new CacheControl.Builder();
if (!NetworkPolicy.shouldReadFromDiskCache(networkPolicy)) {
builder.noCache();
}
if (!NetworkPolicy.shouldWriteToDiskCache(networkPolicy)) {
builder.noStore();
}
cacheControl = builder.build();
}
}
Request.Builder builder = new Request.Builder().url(uri.toString());
if (cacheControl != null) {
builder.cacheControl(cacheControl);
}
okhttp3.Response response = client.newCall(builder.build()).execute();
int responseCode = response.code();
if (responseCode >= 300) {
response.body().close();
throw new ResponseException(responseCode + " " + response.message(), networkPolicy,responseCode);
}
boolean fromCache = response.cacheResponse() != null;
ResponseBody responseBody = response.body();
return new Response(responseBody.byteStream(), fromCache, responseBody.contentLength());
}
//关闭App时,如果有缓存,关闭DiskLruCache;
@Override public void shutdown() {
if (cache != null) {
try {
cache.close();
} catch (IOException ignored) {}
}
}
}
通过上面的代码已经构建出来一个OkHttp3downloader了,现在只需要将它加载到Picasso中去执行就好了;(注意:构建的picasso实例为一个单例,所以需要在Application中去创建这个实例,然后在调用的地方获取picasso单例即可);我是这样写的:
Picasso picasso = new Picasso.Builder(this)
.downloader(new OkHttp3Downloader(new OkHttpClient()))
.build();
Picasso.setSingletonInstance(picasso);
调用的时候这样写:
picasso.with(context).load("Path").into(imageView);
好了,Picasso的本地缓存说完了,
Picasso的使用技巧
添加listener:当你的使用picasso加载图片失败的时候,可以通过listener把失败原因打印
Picasso picasso = new Picasso.Builder(this)
.listener(new Picasso.Listener() {
@Override
public void onImageLoadFailed(Picasso picasso, Uri uri, Exception exception) {
//图片加载失败时的操作
}
})
.loggingEnabled(true)// 打log
.indicatorsEnabled(true)// 分辨不同的路径的价值的图片;
.build();
回调:当图片加载成功和失败时的回调;
picasso.with(this)
.load("path")
.into(imageView, new Callback() {
@Override
public void onSuccess() { }
@Override
public void onError() { }
});
Picasso的相关内容就说完了,如果大家有问题请在评论中指出;
推荐一篇文章: 使用Picasso加载带饼状进度条的图片 。
作者:Torang
链接:http://www.jianshu.com/p/9b93737bfa88
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。