2016-06-27 4 views
0

をRxAndroid:私のWebサービスからの医師のリストを取得するためSyncDoctorsの連結観測が必要として動作していない私は1</p> <p>まず自分の観測返し2つの異なるジョブを行う2つの観測持っ

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

私のウェブサービスから患者リストを取得するための

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をI

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()に電話すると、医師と患者はデータベースに保存されません。私はSyncAll()を呼び出すとき

質問はなぜSyncDoctors()SyncPatients()観測onNext関数が呼び出されています!あなたはあなたが最初に(SyncDoctors()とSyncPatientsのそれに加入し、観測可能な作成

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

で.subscribe()を呼び出すことでチェーンを活性化させるため

+0

'SyncAll'で' onError'内e.printStackTraceを追加して、何が起こっているか見てみてください。 –

+0

@R.Zagórskiエラーはありません。問題は、SyncDoctorのonNextが呼び出されていないことです。代わりに、SyncAllのonNextが2回コールされました! – MBH

+0

DAOのすべての操作が同期していると仮定して、すべての操作をメインスレッドで実行してもよろしいですか? – marwinXXII

答えて

1

それは)です。 このObservableを返すと、観測可能な作成時にWeb応答がトリガーされます。それが結果的にチェーンの要素を実行するのであなたは、)(.concatを使用しないでください

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

:その使用.MAP()を解決するために 。 .zip()。first()inteadを使用します。

1つの問題があります。メインスレッドでdb操作を実行します。 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!!!"); 
       } 
      }); 

} 
+0

' zip'はおそらくあなた医師と患者の似たような長さを保証するものではありません。 'zip(obs1.list()、obs2。list()) 'あなたはobservablesを使うことの全体的なポイントを見落としていますし、ブロッキングobservableを使用して、同期して行うこともできます。 –

+2

どちらのメソッドも項目のリストを返しますが、.concat()は最初の観測が完了するのを待ってから2番目のように.zip()はすべてを同時に開始し、すべての結果があるまで待ちます。 –

+0

その事実を逃した。 –

関連する問題