【问题标题】:takeUntil optimized cache and network method with Retrofit, RxJava and GsontakeUntil 使用 Retrofit、RxJava 和 Gson 优化缓存和网络方法
【发布时间】:2017-04-18 04:57:41
【问题描述】:

我正在尝试使用RxJavatakeUntil 运算符实现优化的缓存和网络方法,以从服务器获取数据。我正在使用 Gson 模型来解析来自 API 的 JSON 响应。

由于使用 Gson 模型,我无法从服务器检索数据。因为返回的类型对于网络请求和磁盘缓存都不匹配。

我已经测试了几种方法,但没有成功。

ApiService.java

@GET(ApiConstants.GET_QUESTIONS_URL) Observable<RequestResponse> getQuestions();

ineteractor.java

   public void performGetElQuestions(String query, QuestionsRequestServerCallback callback) {

 getFreshNetworkData()//
        .publish(network ->//
            Observable.merge(network,//
                getCachedDiskData().takeUntil(network)))
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new DisposableObserver<Question>() {
          @Override
          public void onComplete() {
            callback.onQuestionsReady(mQuestionsList);
          }
          @Override
          public void onError(Throwable e) {
            callback.onQuestionsFailed();
          }

          @Override
          public void onNext(Question question) {
            // mQuestionsList is an arraylist
            mQuestionsList.add(question);
          }
        });

interactor.java

private Observable<Question> getFreshNetworkData() {
        return apiService.getQuestions()
              .flatMap(Observable::fromIterable)
              .doOnSubscribe((data) -> new Handler(Looper.getMainLooper())//
                    .post(() -> adapterSubscriptionInfo.add("(network) subscribed")))//
              .doOnComplete(() -> new Handler(Looper.getMainLooper())//
                    .post(() -> adapterSubscriptionInfo.add("(network) completed")));
    }

缓存数据

     private Observable<Question> getCachedDiskData() {
    List<Question> list = new ArrayList<>();
    //get cached data from SQLite or disk

    return Observable.fromIterable(list)//
        .doOnSubscribe((data) -> new Handler(Looper.getMainLooper())//
            .post(() -> Timber.d("(disk) cache subscribed")))//
        .doOnComplete(() -> new Handler(Looper.getMainLooper())//
            .post(() -> Timber.d("(disk) cache completed")));
  }

Gson 模型解析器

RequestResponse.java

Public class RequestResponse {

    @SerializedName("questions")
    ArrayList<Question> questions;

    public ArrayList<Question> getQuestions() {
        return questions;
    }
}

谢谢:)。

【问题讨论】:

标签: android gson retrofit rx-java rx-java2


【解决方案1】:

我使用领域并利用 RXJava concat + take(1) 的优势,每次我检索数据并缓存它,但如果 innet 连接速度很慢,缓存的数据总是准备好。 Country 实体的代码示例:

 public Observable<ArrayList<Pair<Country,City>>> queryAllAndCopyOrLoad(){
    return Observable.concat(

        Observable.just(storageInteractor.queryAllAndCopySync(Country.class))
            .filter(RxPretty::notEmpty)
            .subscribeOn(AndroidSchedulers.mainThread()),

        networkService.serverApi()
            .getCountries()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .doOnNext(countries -> storageInteractor.deleteAllAndPut(countries, Country.class))
            .doOnNext(countries -> firstTime = false))

        .take(1)
        .flatMap(this::transformToCityCountryPair);
  }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-24
    • 2017-10-03
    • 1970-01-01
    • 1970-01-01
    • 2016-11-09
    • 2023-03-15
    • 2015-04-27
    相关资源
    最近更新 更多