android - RxJava 与 android 存储库模式

标签 android repository-pattern rx-java2 android-room

我正在使用带有存储库模式的 RxJavaRoom 作为数据库,Retrofit 从 api 获取数据。这是我的 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调用:

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

目前我正在使用 concatArray 运算符从数据库和 api 获取数据。但是只有当且仅当我从数据库中什么也得不到时才想调用 api。我想将数据保存到数据库中。我应该使用哪个运算符来达到我的目的?

此外, 我想在将数据插入数据库时​​更新我的​​ View 。因此,我将更改此方法

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

进入这个

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

最佳答案

您可以使用以下内容

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

如果您从第一个流中获取值,则不会执行第二个流。

关于那个有一篇很好的文章here

关于android - RxJava 与 android 存储库模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48034960/

相关文章:

java - 如果已在 Android 中单击,如何防止第二次单击单选按钮?

c# - 存储库模式仅检索所需的列

c# - 将存储库依赖项注入(inject)工作单元

c# - 为什么不使用存储库返回部分域模型结果

java - 获取 RxJava2 中 observable 发出的最后 N 个对象

android - 使用 dispose handler rxjava 创建 Observable

android - react-native map 没有为 android 加载(空白 map )

java - RelativeLayout 中的 ImageView 与父级不匹配

android - Build.GetSerial() 在 API 29 上返回未知数

java - 主线程中的SubscribeOn和observeOn