retrofit框架怎么实现一次请求先返回缓存数据,在返回网络数据?

现在有一个需求,不管网络是否可用,先加载本地缓存,如果网络可用,同时请求网络数据,成功返回的话就展示最新数据。这样提高了用户体验,不至于网络差的情况页面一片空白。但是retrofit这个框架好像不能实现,它是通过添加拦截器实现自定义缓存,一次请求,要么返回缓存数据,要么返回网络数据,不能同时返回两者

/**
     * 缓存策略
     */
    private static final Interceptor cacheControlInterceptor = new Interceptor() {

        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            if (!NetWorkUtils.isNetworkAvailable(GApp.getInstance())) {
                request = request.newBuilder().cacheControl(CacheControl.FORCE_CACHE).build();
                Log.i("ww", "no network");
            }
            Response response = chain.proceed(request);

            if (NetWorkUtils.isNetworkAvailable(GApp.getInstance())) {
                //   String cacheControl = request.cacheControl().toString();
                return response.newBuilder()
                        .header("Cache-Control", CACHE_CONTROL_NETWORK)
                        .removeHeader("Pragma")
                        .build();
            } else {
                return response.newBuilder()
                        .header("Cache-Control", "public, " + CACHE_CONTROL_CACHE)
                        .removeHeader("Pragma")
                        .build();
            }
        }
    };
阅读 4.3k
2 个回答
新手上路,请多包涵

自己写本地缓存功能

用Repository模式的话可以实现
首先参考Android-MVP了解Repository模式

Retrofit是属于网络请求框架,所以在Repository模式里面属于RemoteDataSource,不应该处理缓存相关的事务。缓存的处理在Repository类里实现,从远程抓取数据的时候会把它进行持久化,然后再次请求就可以先从本地获取了。

这是我以前自己的一个例子,
先从本地DataSource请求数据,请求成功后的回调里面发起远程请求,请求失败的回调里也会发起远程请求,这样结果回调会执行两次,可以达到你说的效果。

@Override
public void grabCatalog(@NonNull final String novelId, final GetDataCallback<Catalog> callback,
        final LoadingCallback loadingCallback) {
    mCatalogLocalDataSource.getCatalog(novelId, new GetDataCallback<Catalog>() {
        @Override
        public void onDataLoaded(@NonNull Catalog catalog) {
            callback.onDataLoaded(catalog);
            mCatalogRemoteDataSource.getCatalog(novelId, new GetDataCallback<Catalog>() {
                @Override
                public void onDataLoaded(@NonNull Catalog catalog) {
                    catalog.setNovelId(novelId);
                    callback.onDataLoaded(catalog);
                    mCatalogLocalDataSource.saveCatalog(catalog);
                    refreshCache(catalog);
                }

                @Override
                public void onDataNotAvailable(Error error) {
                    // do nothing
                }
            });
        }

        @Override
        public void onDataNotAvailable(Error error) {
            loadingCallback.onShowLoading();
            mCatalogRemoteDataSource.getCatalog(novelId, new GetDataCallback<Catalog>() {
                @Override
                public void onDataLoaded(@NonNull Catalog catalog) {
                    catalog.setNovelId(novelId);
                    callback.onDataLoaded(catalog);
                    mCatalogLocalDataSource.saveCatalog(catalog);
                    refreshCache(catalog);
                    loadingCallback.onHideLoading();
                }

                @Override
                public void onDataNotAvailable(Error error) {
                    // loadingCallback.onHideLoading();
                    callback.onDataNotAvailable(error);
                }
            });
        }
    });
}
推荐问题