2017-07-29 3 views
0

私はApiRestで塗りつぶされたautocompleteTextViewアダプターをコーディングしています。私はrxJavaとRetrofit 2を使用していますが、非同期関数の値を返す方法がわからないため、フィルタ結果を取得できません。ここに私のコードRxJavaまたはRetrofit2でApiRestを消費するAutoCompleteTextViewアダプタのFilterResultsを返す方法

public class DiagnosticoAutoCompleteAdapter extends BaseAdapter implements Filterable { 
... 
@Override 
public Filter getFilter() { 
    Filter filter = new Filter() { 
     @Override 
     protected FilterResults performFiltering(CharSequence charSequence) { 

      final FilterResults filterResults= new FilterResults(); 
      if(charSequence!=null) { 
       ApiUtils.getAPIServiceDos() 
         .getDiagnosticos(charSequence.toString()) 
         .subscribeOn(Schedulers.io()) 
         .observeOn(AndroidSchedulers.mainThread()) 
         .subscribe(new Observer<List<Diagnostico>>() { 
          @Override 
          public void onSubscribe(Disposable d) { 

          } 

          @Override 
          public void onNext(List<Diagnostico> value) { 
// HERE IT SHOWS ME THE SIZE E.G. 45 so The values are received correctly 
           System.out.println("tamaño diagnostico::"+value.size()); 
// HERE IT SHOWS ME THE OBJECT NAME IN POSITION 0 AND ITS OK         
System.out.println("contenido diagg...."+value.get(0).getNombre()); 
           filterResults.values=value; 
           filterResults.count=value.size(); 
          } 

          @Override 
          public void onError(Throwable e) { 

          } 

          @Override 
          public void onComplete() { 

          } 
         }); 
      } 


//here i lost the information. the count is 0 
      System.out.println("tamaño de filtered results::"+filterResults.count); 
      return filterResults; 
     } 

RxJava要求がOKに動作しますが、値を返すことはできませんです。

私の質問は、フィルタリングされた結果を返す方法です。

答えて

0

問題は、非同期操作が非同期操作を開始していることを意味する非同期操作を実行していることを意味し、空のFilterResultsを直ちに返して非同期操作が実行されず、 performFilteringメソッド内に戻す前に、FilterResultsを空に戻した後に、非同期操作(Observer.onNext内)の結果が変更されます。

Filterオブジェクトがすでにバックグラウンドスレッド上の実際の仕事をしているの力仕事を行う抽象クラス、performFilteringmethod invoked in a worker threadで、あなたはpublishResults方法でUIスレッドで結果を処理する必要があります。

このAPIは、RxJavaリアクティブモデルにはまったく適していません。performFilteringで直接サーバー呼び出しを呼び出して、ワーカースレッドで呼び出されたときに結果を返すことができます。
あなたがRxJavaをしたい場合、あなたはブロック1にストリームを変換して、それを行うと、結果を返すことができます。

@Override 
protected FilterResults performFiltering(CharSequence charSequence) { 

    final FilterResults filterResults = new FilterResults(); 
    if (charSequence != null) { 
     List<Diagnostico> value = ApiUtils.getAPIServiceDos() 
       .getDiagnosticos(charSequence.toString()) 
       .toBlocking() 
       .first(); 
     System.out.println("tamaño diagnostico::" + value.size()); 
     System.out.println("contenido diagg...." + value.get(0).getNombre()); 
     filterResults.values = value; 
     filterResults.count = value.size(); 
    } 
    return filterResults; 
} 

EDIT:なぜあなたはpublishResultsで非同期要求を発射するべきではありません。

publishResultsでリクエストを実行すると、結果が得られた後にUIを更新するように設計されているように機能します(おそらくアダプタに通知する)ので、bgでリクエストを実行した後にメインスレッドに戻り、アダプタを更新します。

しかし、適切なフィルタリングのライフサイクルに縛られていないため、進捗状況がすぐに消え、結果をバックグラウンドで実際に取得している間は表示されません以前の要求が後の要求の後に到着し、古いデータでアダプタを更新する可能性があるため、複数の要求が発生したときにバグが発生します。そのため、フィルタAPIに従って、performFilteringでブロックするようにリクエストを実行する必要があります。

+0

リクエストを変更して@Overrideメソッドに入れて問題を解決します。 protected void publishResults(CharSequence charSequence – matQ

+0

リクエストを 'publishResults' – yosriz

関連する問題