2017-12-30 23 views
0

私はRxJavaリポジトリパターンで、Roomをデータベースとして使用し、Retrofitを使用してapiからデータを取得しています。アンドロイドリポジトリパターンのRxJava

public interface BcsQuestionService { 
    @GET("get/bTQwGnFsky?indent=2") 
    Observable<List<SubjectModel>> getAllSubject(); 
} 

そして、ここでは私のリポジトリです:

public class SubjectRepo extends BaseRepo { 

    private static final String TAG = "SubjectRepo"; 

    @Inject 
    public SubjectRepo(DataManager dataManager, SubjectService apiService) { 
     super(dataManager, apiService); 
    } 

    public Observable<List<SubjectModel>> getSubjectList() { 
     return Observable 
       .concatArray(getDbSubjectList(), getApiSubjectList()) 
       .observeOn(AndroidSchedulers.mainThread()); 
    } 

    public Observable<List<SubjectModel>> getDbSubjectList() { 
     return mDataManager.getSubjectList() 
       .filter(new Predicate<List<SubjectEntity>>() { 
        @Override 
        public boolean test(List<SubjectEntity> subjectEntities) throws Exception { 
         return !ListUtils.isEmpty(subjectEntities); 
        } 
       }).map(new Function<List<SubjectEntity>, List<SubjectModel>>() { 
        @Override 
        public List<SubjectModel> apply(List<SubjectEntity> subjectEntities) throws Exception { 
         List<SubjectModel> models = new ArrayList<>(); 
         for (SubjectEntity entity: subjectEntities) { 
          SubjectModel model = new SubjectModel(); 
          model.setId(entity.getId()); 
          model.setName(entity.getName()); 
         } 
         return models; 
        } 
       }) 
       .subscribeOn(Schedulers.io()) 
       .toObservable(); 
    } 

    public Observable<List<SubjectModel>> getApiSubjectList() { 
     return mApiService.getAllSubject() 
       .doOnNext(new Consumer<List<SubjectModel>>() { 
        @Override 
        public void accept(List<SubjectModel> subjectModels) throws Exception { 
         List<SubjectEntity> entities = new ArrayList<>(); 
         for (SubjectModel model: subjectModels) { 
          SubjectEntity entity = new SubjectEntity(); 
          entity.setId(model.getId()); 
          entity.setName(model.getName()); 
         } 
         mDataManager.insertSubjectListEntity(entities); 
        } 
       }); 
    } 
} 

現在、私は、データベースやAPIからデータを取得するためにconcatArray演算子を使用しています。ここに私Dao

@Dao 
public interface SubjectDao { 

    @Insert(onConflict = OnConflictStrategy.REPLACE) 
    void insert(SubjectEntity... subjects); 

    @Insert(onConflict = OnConflictStrategy.REPLACE) 
    void insertSubjectEntities(List<SubjectEntity> subjectEntities); 

    @Insert(onConflict = OnConflictStrategy.IGNORE) 
    long createSubjectIfNotExists(SubjectEntity subject); 

    @Query("SELECT * FROM "+ DbConstants.SUBJECT_LIST_NAME) 
    Single<List<SubjectEntity>> getAllSubjects(); 

} 

API呼び出しがあります。しかし、私はデータベースから何も得られない場合にのみ、APIを呼びたいと思う。そして、データをデータベースに保存したいと思います。私の目的を達成するためにどのオペレーターを使うべきですか?

さらに、 データがデータベースに挿入されるときに私のビューを更新したいと思います。そのため、私はあなたから値を取得する場合は、

public Observable<List<SubjectModel>> getSubjectList() { 
    return Observable 
      .concat(getDbSubjectList(), getApiSubjectList()) 
      .first(); 
} 

次これは、第二の流れを実行しません使用することができ、この

@Query("SELECT * FROM "+ DbConstants.SUBJECT_LIST_NAME) 
Flowable<List<SubjectEntity>> getAllSubjects(); 

答えて

1

にこの方法

@Query("SELECT * FROM "+ DbConstants.SUBJECT_LIST_NAME) 
Single<List<SubjectEntity>> getAllSubjects(); 

を変更します最初の1つ。この場合、そのhere

+0

についての素晴らしい記事があります

データがデータベースに挿入されたとき、 'Room'は')( '最初の原因となるビューを更新するために、加入者に通知しません' SingleObserber'を返します。 – CodeCameo