Android Okhttp缓存:精细化每一个Request的CacheControl缓存控制策略(二)
之前我写的附录文章1,只是简单的使用缺省的方法实现Okhttp的缓存。现在使用CacheControl,精细化到每一个Request的缓存控制策略。
改造附录1代码:
package zhangphil.app;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.widget.ImageView;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import okhttp3.Cache;
import okhttp3.CacheControl;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class MainActivity extends AppCompatActivity {
private OkHttpClient mOkHttpClient;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ImageView image = (ImageView) findViewById(R.id.image);
File cacheDir = new File(this.getCacheDir(), "zhangphilcache");
Cache mCache = new Cache(cacheDir, 8 * 1024 * 1024); //8M缓存空间
OkHttpClient.Builder mBuilder = new OkHttpClient.Builder();
mOkHttpClient = mBuilder
.connectTimeout(10, TimeUnit.SECONDS) //连接超时阈值
.writeTimeout(10, TimeUnit.SECONDS) //写超时阈值
.readTimeout(10, TimeUnit.SECONDS) //读超时阈值
.retryOnConnectionFailure(true) //当失败后重试
.cache(mCache)
.build();
String url = "https://www.baidu.com/img/bd_logo1.png";
CacheControl mCacheControl = new CacheControl.Builder()
.noTransform()
.maxAge(60 * 60, TimeUnit.SECONDS) //缓存有效期时长
.build();
Request mRequest = new Request.Builder()
.url(url)
.cacheControl(mCacheControl)
.build();
mOkHttpClient.newCall(mRequest).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
byte[] bytes = response.body().bytes();
final Bitmap bmp = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
runOnUiThread(new Runnable() {
@Override
public void run() {
image.setImageBitmap(bmp);
}
});
}
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
//取消所有Okhttp的网络请求
mOkHttpClient.dispatcher().cancelAll();
}
}
maxAge 缓存有效期,Okhttp源代码中maxAge的实现:
/**
* Sets the maximum age of a cached response. If the cache response's age exceeds {@code
* maxAge}, it will not be used and a network request will be made.
*
* @param maxAge a non-negative integer. This is stored and transmitted with {@link
* TimeUnit#SECONDS} precision; finer precision will be lost.
*/
public Builder maxAge(int maxAge, TimeUnit timeUnit) {
if (maxAge < 0) throw new IllegalArgumentException("maxAge < 0: " + maxAge);
long maxAgeSecondsLong = timeUnit.toSeconds(maxAge);
this.maxAgeSeconds = maxAgeSecondsLong > Integer.MAX_VALUE
? Integer.MAX_VALUE
: (int) maxAgeSecondsLong;
return this;
}
CacheControl.Builder在build时候的常用方法:
noCache 不使用缓存。
noStore 不要把网络数据缓存。
noTransform 不要转码。
Okhttp定义了若干常量缓存模型:
CacheControl.FORCE_NETWORK 强制使用网络数据。
CacheControl.FORCE_CACHE 强制使用缓存。
注意看Okhttp源码实现,在Okhttp源代码文件CacheControl.java中,CacheControl.FORCE_NETWORK的代码实现:
public static final CacheControl FORCE_NETWORK = new Builder().noCache().build();
CacheControl.FORCE_CACHE的代码实现:
/**
* Cache control request directives that uses the cache only, even if the cached response is
* stale. If the response isn't available in the cache or requires server validation, the call
* will fail with a {@code 504 Unsatisfiable Request}.
*/
public static final CacheControl FORCE_CACHE = new Builder()
.onlyIfCached()
.maxStale(Integer.MAX_VALUE, TimeUnit.SECONDS)
.build();
附录:
1,《Android Okhttp缓存:Cache,创建OkHttpClient实现(一)》链接:http://blog.csdn.net/zhangphil/article/details/78326497