在使用Picasso和okhttp这些开源的框架时,由于okttp已经升级到okhttp3,同时okhttp3的包名也随之改变了,从
com.squareup.okhttp变成了okhttp3 。
而Picasso中的OkHttpDownloader引用的包名还是
com.squareup.okhttp 这个包名。
所以在修改Picasso的图片缓存路劲时,即使用该段代码
Picasso picasso = Picasso.Builder(context).downloader(
OkhttpDownLoader(getDiskCacheDir(context))).build();
时,就会报错,无法使用。
解决法1:
不升级到okhttp3。
解决方法2:
自己写一个
OkhttpDownLoader
工具类。即修改上面那个类的代码,代码如下:
public class MyOkhttpDownLoader implements Downloader {
private static final int MIN_DISK_CACHE_SIZE = 5 * 1024 * 1024; // 5MB
private static final int DEFAULT_CONNECT_TIMEOUT_MILLIS = 15 * 1000; // 15s
private static final int DEFAULT_READ_TIMEOUT_MILLIS = 20 * 1000; // 20s
private static final int DEFAULT_WRITE_TIMEOUT_MILLIS = 20 * 1000; // 20s
private static final int MAX_DISK_CACHE_SIZE = 50 * 1024 * 1024; // 50MB
private static final String PICASSO_CACHE = "picasso-cache";
private static OkHttpClient.Builder defaultOkHttpClientBuilder() {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.connectTimeout(DEFAULT_CONNECT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
builder.readTimeout(DEFAULT_READ_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
builder.writeTimeout(DEFAULT_WRITE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
return builder;
}
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 final OkHttpClient client;
private final OkHttpClient.Builder builder;
public MyOkhttpDownLoader(final Context context) {
this(createDefaultCacheDir(context));
}
public MyOkhttpDownLoader(OkHttpClient.Builder builder){
this.builder = builder;
this.client = this.builder.build();
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
static long calculateDiskCacheSize(File dir) {
long size = MIN_DISK_CACHE_SIZE;
try {
StatFs statFs = new StatFs(dir.getAbsolutePath());
long available = 0l;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2){
available = statFs.getBlockCountLong() * statFs.getBlockSizeLong();
}else{
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);
}
public MyOkhttpDownLoader(final File cacheDir){
this(cacheDir,calculateDiskCacheSize(cacheDir));
}
protected final OkHttpClient getClient() {
return client;
}
protected final OkHttpClient.Builder getBuilder() {
return builder;
}
public MyOkhttpDownLoader(final File cacheDir,long maxSize){
this(defaultOkHttpClientBuilder());
try {
builder.cache(new okhttp3.Cache(cacheDir, maxSize));
} catch (Exception ignored) {
}
}
public MyOkhttpDownLoader(final Context context, final long maxSize) {
this(createDefaultCacheDir(context), maxSize);
}
@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();
}
}
okhttp3.Request.Builder builder = new okhttp3.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());
}
@Override
public void shutdown() {
okhttp3.Cache cache = client.cache();
if (cache != null) {
try {
cache.close();
} catch (IOException ignored) {
}
}
}
}