鍍金池/ 問答/Android/ retrofit框架怎么實(shí)現(xiàn)一次請求先返回緩存數(shù)據(jù),在返回網(wǎng)絡(luò)數(shù)據(jù)?

retrofit框架怎么實(shí)現(xiàn)一次請求先返回緩存數(shù)據(jù),在返回網(wǎng)絡(luò)數(shù)據(jù)?

現(xiàn)在有一個需求,不管網(wǎng)絡(luò)是否可用,先加載本地緩存,如果網(wǎng)絡(luò)可用,同時請求網(wǎng)絡(luò)數(shù)據(jù),成功返回的話就展示最新數(shù)據(jù)。這樣提高了用戶體驗(yàn),不至于網(wǎng)絡(luò)差的情況頁面一片空白。但是retrofit這個框架好像不能實(shí)現(xiàn),它是通過添加攔截器實(shí)現(xiàn)自定義緩存,一次請求,要么返回緩存數(shù)據(jù),要么返回網(wǎng)絡(luò)數(shù)據(jù),不能同時返回兩者

/**
     * 緩存策略
     */
    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();
            }
        }
    };
回答
編輯回答
安淺陌

用Repository模式的話可以實(shí)現(xiàn)
首先參考Android-MVP了解Repository模式

Retrofit是屬于網(wǎng)絡(luò)請求框架,所以在Repository模式里面屬于RemoteDataSource,不應(yīng)該處理緩存相關(guān)的事務(wù)。緩存的處理在Repository類里實(shí)現(xiàn),從遠(yuǎn)程抓取數(shù)據(jù)的時候會把它進(jìn)行持久化,然后再次請求就可以先從本地獲取了。

這是我以前自己的一個例子,
先從本地DataSource請求數(shù)據(jù),請求成功后的回調(diào)里面發(fā)起遠(yuǎn)程請求,請求失敗的回調(diào)里也會發(fā)起遠(yuǎn)程請求,這樣結(jié)果回調(diào)會執(zhí)行兩次,可以達(dá)到你說的效果。

@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);
                }
            });
        }
    });
}
2018年4月30日 13:50
編輯回答
喵小咪

自己寫本地緩存功能

2017年9月9日 19:34