连接可观察量不符合要求 - RxAndroid

时间:2016-06-27 14:11:09

标签: android rx-java rx-android

我有2个Observable,可以执行2个不同的工作,返回他们的observables

第一个: SyncDoctors ,用于从我的WebService获取医生列表

public Observable<List<Doctor>> SyncDoctors(){
    Observable<List<Doctor>> observable = MyWebService.getInterface().GetAllDoctors();
    observable.observeOn(AndroidSchedulers.mainThread())
            .subscribeOn(Schedulers.computation())
            .subscribe(new Subscriber<List<Doctor>>() {
                @Override
                public void onCompleted() {
                }

                @Override
                public void onError(Throwable e) {
                }

                @Override
                public void onNext(List<Doctor> doctors) {
                    if(doctors.size() == 0){
                        logger.debug("No Coming Doctors");
                        return;
                    }

                    DoctorDao doctorDao = MyApplication.getDaoSession().getDoctorDao();
                    doctorDao.deleteAll();

                    doctorDao.insertInTx(doctors);

                    logger.debug("Doctors are synced successfully to the database");
                    logger.info(doctors.size()+" doctors have been added to database");
                }
            });
    return observable;
}

Second Observable 用于从我的网络服务中获取患者列表

public Observable<List<Patients>> SyncPatients(){
    Observable<List<Patients>> observable = MyWebService.getInterface().GetAllPatients();
    observable.observeOn(AndroidSchedulers.mainThread())
            .subscribeOn(Schedulers.computation())
            .subscribe(new Subscriber<List<Patients>>() {
                @Override
                public void onCompleted() {
                }

                @Override
                public void onError(Throwable e) {
                }

                @Override
                public void onNext(List<Patients> patients) {
                    if(patients.size() == 0){
                        logger.debug("No Coming Patients");
                        return;
                    }

                    PatientDao PatientDao = MyApplication.getDaoSession().getPatientDao();
                    patientDao.deleteAll();

                    PatientDao.insertInTx(Patients);

                    logger.debug("Patients are synced successfully to the database");
                    logger.info(Patients.size()+" Patients have been added to database");
                }
            });
    return observable;
}

现在我想同步医生和患者名单,同步完成后,我想在平板电脑的屏幕上显示:

我有一个名为 SyncAll

的功能
public void SyncAll(){

    Observable<List<Doctor>> doctorsObservable = SyncDoctors();
    Observable<List<Patient>> patientsObservable = SyncPatients();

    Observable.concat(doctorsObservable, patientsObservable)
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeOn(Schedulers.computation())
            .subscribe(new Subscriber<Object>() {
                @Override
                public void onCompleted() {
                    // Here the code to show on ListView
                }

                @Override
                public void onError(Throwable e) {

                }

                @Override
                public void onNext(Object o) {
                    logger.debug("On SyncAll Next!!!");
                }
            });
}

onNext函数我将医生列表和患者列表保存到数据库中。

现在当我单独打电话给SyncDoctors()时,它就可以了 当我单独打电话给SyncPatients()时,它也会起作用。

当我致电SyncAll()时,医生和患者没有被保存到数据库中。

问题是我致电SyncDoctors()时调用SyncPatients()SyncAll()可观察的'onNext函数的原因!!

1 个答案:

答案 0 :(得分:1)

这是因为您通过调用

中的.subscribe()来激活链
Observable<List<Doctor>> doctorsObservable = SyncDoctors();
Observable<List<Patient>> patientsObservable = SyncPatients();

首先创建observable,然后订阅SyncDoctors()和SyncPatients(); 之后返回此Observable,但在可观察的创建时触发Web响应。 要解决这个问题,请使用.map():

public Observable<List<Doctor>> SyncDoctors(){
        final Observable<List<Doctor>> observable = MyWebService.getInterface().GetAllDoctors();
        observable.observeOn(Schedulers.io())
                // in your code you performed db io on main thread, here it is fixed
                .subscribeOn(Schedulers.io())
                .map(new Func1<List<Doctor>, List<Doctor>>() {
                    @Override
                    public List<Doctor> call(List<Doctor> doctors) {
                        if(doctors.size() == 0){
                            logger.debug("No Coming Doctors");
                            return;
                        }

                        DoctorDao doctorDao = MyApplication.getDaoSession().getDoctorDao();
                        doctorDao.deleteAll();

                        doctorDao.insertInTx(doctors);

                        logger.debug("Doctors are synced successfully to the database");
                        logger.info(doctors.size()+" doctors have been added to database");
                        return doctors;
                    }
                })
                .observeOn(AndroidSchedulers.mainThread());
        // Notice: use Observable.defer() or you'll get the same result all the tim
        return Observable.defer(new Func0<Observable<List<Doctor>>>() {
            @Override
            public Observable<List<Doctor>> call() {
                return observable;
            }
        });
    }

您不应该使用.concat(),因为它会执行链元素。使用.zip()。first()intead。

还有一个问题:您在主线程上执行数据库操作。 在db update

之后将链移动到主线程

.zip版本:

void syncAll(){
    Observable<List<Doctor>> doctorsObservable = SyncDoctors();
    Observable<List<Patient>> patientsObservable = SyncPatients();
    Observable.zip(doctorsObservable, patientsObservable, new Func2<List<Doctor>, List<Patient>, Boolean>() {
        @Override
        public Boolean call(List<Doctor> doctors, List<Patient> patients) {
            return true;
        }
    })
            .first()
            .subscribe(new Action1<Boolean>() {
                @Override
                public void call(Boolean aBoolean) {
                    logger.debug("On SyncAll Next!!!");
                }
            });

}