2016-12-03 69 views
1

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

由于使用Gson模型,我陷入从服务器检索数据的困境。因为返回的类型与Netwrok请求和磁盘缓存不匹配。

我一直在测试几种方法,但没有成功地把它做对。

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; 
    } 
} 

谢谢:)。

+0

什么是你从服务器得到JSON? – iagreen

+0

嘿@iagreen,https://gist.github.com/alouanemed/65fb8069d15edfe1cc49dbe0973111f2 –

+0

请显示错误stacktrace –

回答

0

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

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); 
    }