我正在使用改造2来进行API调用,但我的问题是API响应需要时间来显示响应,我是否有机会存储数据并加载缓存并显示它然后同时调用网络API。
例如:
第一次点击 - >进行网络呼叫 - 将输出渲染到屏幕上,说明列表视图 - >将响应存储在缓存中
下次用户进入屏幕时 - >加载缓存并将其渲染到屏幕 - >进行网络通话 - >使用更改刷新适配器
指的是一个要点链接 https://gist.github.com/Tetr4/d10c5df0ad9218f967e0
答案 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评论,我刚刚更新了这个答案。我希望现在好多了。