Android - Retrofit& amp;中的缓存逻辑OkHttp

时间:2017-04-23 14:37:32

标签: android caching retrofit2 okhttp

这是我想要实现的:

enter image description here

如果有连接:

  • 数据已在1小时前更新:更新数据
  • 数据更新时间不到1小时:从缓存中获取数据

如果没有连接:

  • 数据已于48小时前更新:显示消息"没有互联网 连接"
  • 数据更新时间不到48小时:从缓存中获取数据

这是我的REST客户端模块,我尝试在陈述逻辑之前实现。

@Module
public class DarkSkyApiModule {

    public final String BASE_URL = "https://api.darksky.net";

    private static final Interceptor REWRITE_CACHE_CONTROL_INTERCEPTOR = new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Response originalResponse = chain.proceed(chain.request());
            if (NetworkUtil.isNetworkAvailable()) {
                int maxAge = 60 * 60; // read from cache for 1 hour
                return originalResponse.newBuilder()
                        .header("Cache-Control", "public, max-age=" + maxAge)
                        .build();
            } else {
                int maxStale = 60 * 60 * 48; // tolerate 48-hours stale
                return originalResponse.newBuilder()
                        .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
                        .build();
            }
        }
    };

    @Provides
    public OkHttpClient provideClient() {

        //setup cache
        File httpCacheDirectory = new File(FileManager.getCacheDir(), "responses");
        int cacheSize = 10 * 1024 * 1024; // 10 MiB
        Cache cache = new Cache(httpCacheDirectory, cacheSize);

        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

        return new OkHttpClient.Builder()
                .addNetworkInterceptor(REWRITE_CACHE_CONTROL_INTERCEPTOR)
                .addInterceptor(interceptor)
                .cache(cache)
                .build();

    }

    @Provides
    public Retrofit provideRetrofit(String baseURL, OkHttpClient client) {
        return new Retrofit.Builder()
                .baseUrl(baseURL)
                .client(client)
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }

    @Provides
    public DarkSkyApiService provideApiService() {
        return provideRetrofit(BASE_URL, provideClient()).create(DarkSkyApiService.class);
    }

}

但结果不如预期: 如果有连接:

  • 数据已在1小时前更新:
  

D / OkHttp:Cache-Control:public,max-age = 3600   W / System.err:删除失败:ENOENT(没有这样的文件或目录):   /data/user/0/com.android.example/cache/responses/2fb62bf59f85c3371d74d511a3bbeac2.0   W / System.err:删除失败:ENOENT(没有这样的文件或目录):/ data / user / //com.android.example/cache/responses/2fb62bf59f85c3371d74d511a3bbeac2.1   D / OkHttp:[json_data]

  • 数据在不到1小时前更新:
  

D / OkHttp:Cache-Control:public,max-age = 3600   W / System.err:删除失败:ENOENT(没有这样的文件或目录):   /data/user/0/com.android.example/cache/responses/2fb62bf59f85c3371d74d511a3bbeac2.0   W / System.err:删除失败:ENOENT(没有这样的文件或目录):/ data / user / //com.android.example/cache/responses/2fb62bf59f85c3371d74d511a3bbeac2.1   D / OkHttp:[json_data]

如果没有连接:

  • 数据已在1小时前更新:
  

无法解析主持人" api.darksky.net":没有与之关联的地址   主机名

  • 数据在48小时前更新:
      

    W / System.err:删除失败:ENOENT(没有这样的文件或目录):/ data / user / / com.android.example / cache / respond / journal.tmp   D / OkHttp:Cache-Control:public,max-age = 3600   D / OkHttp:[json_data]

FileManager.java

public class FileManager {

    static Context context;

    public static void init(Context c) {
        context = c;
    }

    public static File getCacheDir(){
        return context.getCacheDir();
    }

}

如何解决这个问题?我应该设置为max-age和max-stale?

0 个答案:

没有答案