在网络呼叫之前改造2加载缓存

时间:2017-10-21 12:23:15

标签: android retrofit2

我正在使用改造2来进行API调用,但我的问题是API响应需要时间来显示响应,我是否有机会存储数据并加载缓存并显示它然后同时调用网络API。

例如:

第一次点击 - >进行网络呼叫 - 将输出渲染到屏幕上,说明列表视图 - >将响应存储在缓存中

下次用户进入屏幕时 - >加载缓存并将其渲染到屏幕 - >进行网络通话 - >使用更改刷新适配器

指的是一个要点链接 https://gist.github.com/Tetr4/d10c5df0ad9218f967e0

2 个答案:

答案 0 :(得分:5)

是的,有很多解决办法。

如果您使用 RxJava (适用于retrofit),这是解决方案。

首先使用concat,如:

Observable<Data> source = Observable  
  .concat(memory, disk, network).first();

内存,磁盘和网络都是Observables。这将是第一次。这意味着如果缓存可用,请使用缓存,否则使用磁盘,否则使用网络。

问题在于,一旦有了缓存,它就永远不会进入网络。这就是为什么你应该这样做的原因:

 getRemoteItems().publish { Flowable.merge(it,  getLocalItems().takeUntil(it)) }

这将同时获取远程和本地,但在获取远程数据后停止本地。您可以使用doOnSuccess使用

使用远程数据填充本地数据库

是的,有很多解决办法。

首先使用concat,如:

Observable<Data> source = Observable  
  .concat(memory, disk, network).first();

内存,磁盘和网络都是Observables。这将是第一次。这意味着如果缓存可用,请使用缓存,否则使用磁盘,否则使用网络。

问题在于它一旦有了缓存就永远不会进入网络。这就是为什么你应该这样做的原因:

 getRemoteItems()
        .doOnSuccess { storeToLocal(it) }
        .publish { Flowable.merge(it,  getLocalItems().takeUntil(it)) }

这意味着它在尝试获取缓存的同时获取远程项目。如果能够获取远程数据,则将数据存储到缓存中。

如果您在没有first()的情况下使用第一个示例,它将在最坏的情况下提供3次Data,但要等到之前的observable完成。这意味着它将尝试内存,一旦内存调用onComplete()它就会进入磁盘。如果磁盘已完成,请尝试使用网络。

Observable<Data> source = Observable  
      .concat(memory, disk, network) 

答案 1 :(得分:1)

您可以先缓存所有回复:

public static Retrofit getAdapter(Context context, String baseUrl) {
    OkHttpClient.Builder okHttpClient = new OkHttpClient().newBuilder();
    Cache cache = new Cache(getCacheDir(), cacheSize);

    okHttpClient.cache(cache).build();

    Retrofit.Builder retrofitBuilder = new Retrofit.Builder();
    retrofitBuilder.baseUrl(baseUrl).client(okHttpClient);
    return retrofitBuilder.build();
}

在下一次网络通话中,您可以检查响应是否已更改。如果是这样,那么你得到新的回复,如果没有,那么你不需要刷新你的适配器:

if (response.isSuccessful() &&
    response.raw().networkResponse() != null &&
    response.raw().networkResponse().code() ==
       HttpURLConnection.HTTP_NOT_MODIFIED) {
    // the response hasn't changed, so you do not need to do anything
    return;
}
// otherwise, you can get the new response and refresh your adapter
...

关注@vsync评论,我刚刚更新了这个答案。我希望现在好多了。

参考文献:https://android.jlelse.eu/reducing-your-networking-footprint-with-okhttp-etags-and-if-modified-since-b598b8dd81a1