オブザーバブルを返す2つの異なるジョブを実行する2つのオブザーバブルがあります
最初のもの:私のWebサービスから医師リストを取得するためのSyncDoctors
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;
}
私のWebサービスから患者リストを取得するための2番目の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()
私が呼ぶとき観測onNext関数が呼び出されますSyncAll()
!
これは、で.subscribe()を呼び出してチェーンをアクティブ化するためです。
Observable<List<Doctor>> doctorsObservable = SyncDoctors();
Observable<List<Patient>> patientsObservable = SyncPatients();
最初にobservableを作成し、次にSyncDoctors()とSyncPatients()をサブスクライブします。その後、このObservableを返しますが、Web応答はobservableの作成時にトリガーされます。これを解決するには、.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()を使用してください。
また、1つの問題があります。メインスレッドでdb操作を実行します。データベースの更新後にチェーンをメインスレッドに移動する
.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!!!");
}
});
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加