我真的坚持这个问题。
我希望在设备离线时缓存服务器响应一段时间以使用数据。
所以我为我的OkHttpClient
设置了一个缓存。
我还设置了Cache-Contlol
标题。
这是我的代码:
public class MainActivity extends AppCompatActivity {
Retrofit retrofit;
RecyclerView recyclerView;
RandomUserAdapter mAdapter;
Cache cache;
Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.create();
cache = provideOkHttpCache();
Timber.plant(new Timber.DebugTree());
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
populateUsers();
}
});
Interceptor cacheInterceptor = new Interceptor() {
@Override
public okhttp3.Response intercept(Interceptor.Chain chain) throws IOException {
okhttp3.Response originalResponse = chain.proceed(chain.request());
okhttp3.Response modifyedResponse = originalResponse;
if (true) {
modifyedResponse = originalResponse.newBuilder()
.header("Cache-Control", "max-age=86400")
.build();
}
return modifyedResponse;
}
};
HttpLoggingInterceptor httpLoggingInterceptor = new
HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(@NonNull String message) {
Timber.i(message);
}
});
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient okHttpClient = new OkHttpClient()
.newBuilder()
.addInterceptor(httpLoggingInterceptor)
.addInterceptor(cacheInterceptor)
.cache(cache)
.build();
retrofit = new Retrofit.Builder()
.client(okHttpClient)
.baseUrl("https://randomuser.me/")
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
populateUsers();
}
private void initViews() {
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
button = findViewById(R.id.button);
}
private void populateUsers() {
Call<RandomUsers> randomUsersCall = getRandomUserService().getRandomUsers(10);
randomUsersCall.enqueue(new Callback<RandomUsers>() {
@Override
public void onResponse(Call<RandomUsers> call, @NonNull Response<RandomUsers> response) {
if (response.isSuccessful()) {
Log.v("cache-control", "using cache = " + isFromCache(response));
mAdapter = new RandomUserAdapter();
mAdapter.setItems(response.body().getResults());
recyclerView.setAdapter(mAdapter);
}
}
@Override
public void onFailure(Call<RandomUsers> call, Throwable t) {
Timber.i(t.getMessage());
Log.v("cache-control", "response failure");
}
});
}
public RandomUsersApi getRandomUserService() {
return retrofit.create(RandomUsersApi.class);
}
Cache provideOkHttpCache() {
int cacheSize = 10 * 1024 * 1024; // 100 MiB
File cacheDir = new File("cachedirectory");
Cache cache = new Cache(cacheDir, cacheSize);
return cache;
}
public boolean isFromCache(Response response) {
return response.raw().cacheResponse() != null;
}
}
看起来一切都会好起来的。 然后我这样做:
此时我希望应用程序将使用缓存数据。但事实并非如此。
我的logcat中只有空白屏幕和HTTP FAILED: java.net.UnknownHostException: Unable to resolve host "randomuser.me": No address associated with hostname
。
答案 0 :(得分:1)
好吧,我找到了解决方案。我不确定它为什么会起作用,但确实如此。
首先,我们需要修改def load_table_as_array(filename):
f = open(filename,'r')
# Parsing the first line containing column headers
header_line = f.readline()
header_line = header_line.strip(',\n')
column_names = header_line.split(',’)
#Parsing the rest of the file
mat = []
row_names = []
for line in f:
tokens = line.rstrip().split(',')
row_names.append(tokens[0]) #Add first token to row header list
values = [float(n) for n in tokens[1:]] # Convert to float
mat.append(values) # Append the current row to the matrix
f.close()
row_names = np.array(row_names)
column_names = np.array(column_names)
data = np.array(mat)
return data, column_names, row_names
:
cacheInterceptor
然后我们需要使用 Interceptor cacheInterceptor = new Interceptor() {
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
CacheControl.Builder cacheBuilder = new CacheControl.Builder();
cacheBuilder.maxAge(0, TimeUnit.SECONDS);
cacheBuilder.maxStale(365,TimeUnit.DAYS);
CacheControl cacheControl = cacheBuilder.build();
Request request = chain.request();
if(isOnline()){
request = request.newBuilder()
.cacheControl(cacheControl)
.build();
}
okhttp3.Response originalResponse = chain.proceed(request);
if (isOnline()) {
int maxAge = 60; // read from cache
return originalResponse.newBuilder()
.header("Cache-Control", "public, max-age=" + maxAge)
.build();
} else {
int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale
return originalResponse.newBuilder()
.header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
.build();
}
}
};
代替addNetworkInterceptor(Interceptor interceptor)
:
addInterceptor(Interceptor interceptor)