我有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函数的原因!!
答案 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!!!");
}
});
}