/
OkHttp3Downloader.java
158 lines (137 loc) · 4.82 KB
/
OkHttp3Downloader.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
package com.jakewharton.picasso;
import android.content.Context;
import android.net.Uri;
import android.os.StatFs;
import com.squareup.picasso.Downloader;
import com.squareup.picasso.NetworkPolicy;
import java.io.File;
import java.io.IOException;
import okhttp3.Cache;
import okhttp3.CacheControl;
import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.ResponseBody;
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
private static File defaultCacheDir(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);
}
/**
* Creates a {@link Cache} that would have otherwise been created by calling
* {@link #OkHttp3Downloader(Context)}. This allows you to build your own {@link OkHttpClient}
* while still getting the default disk cache.
*/
public static Cache createDefaultCache(Context context) {
File dir = defaultCacheDir(context);
return new Cache(dir, calculateDiskCacheSize(dir));
}
private static OkHttpClient createOkHttpClient(File cacheDir, long maxSize) {
return new OkHttpClient.Builder()
.cache(new Cache(cacheDir, maxSize))
.build();
}
private final Call.Factory client;
private final Cache cache;
/**
* Create new downloader that uses OkHttp. This will install an image cache into your application
* cache directory.
*/
public OkHttp3Downloader(Context context) {
this(defaultCacheDir(context));
}
/**
* Create new downloader that uses OkHttp. This will install an image cache into the specified
* directory.
*
* @param cacheDir The directory in which the cache should be stored
*/
public OkHttp3Downloader(File cacheDir) {
this(cacheDir, calculateDiskCacheSize(cacheDir));
}
/**
* Create new downloader that uses OkHttp. This will install an image cache into your application
* cache directory.
*
* @param maxSize The size limit for the cache.
*/
public OkHttp3Downloader(final Context context, final long maxSize) {
this(defaultCacheDir(context), maxSize);
}
/**
* Create new downloader that uses OkHttp. This will install an image cache into the specified
* directory.
*
* @param cacheDir The directory in which the cache should be stored
* @param maxSize The size limit for the cache.
*/
public OkHttp3Downloader(File cacheDir, long maxSize) {
this(createOkHttpClient(cacheDir, maxSize));
}
public OkHttp3Downloader(OkHttpClient client) {
this.client = client;
this.cache = client.cache();
}
public OkHttp3Downloader(Call.Factory client) {
this.client = client;
this.cache = null;
}
@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());
}
@Override public void shutdown() {
if (cache != null) {
try {
cache.close();
} catch (IOException ignored) {
}
}
}
}