2017-07-29 70 views
0

我編寫了一個由ApiRest填充的autocompleteTextView適配器。我正在使用rxJava和Retrofit 2.但無法獲得過濾結果,因爲我不知道如何返回異步函數中的值。這裏是我的代碼如何在使用RxJava或Retrofit2的AutoCompleteTextView Adapter中使用ApiRest返回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請求工作正常,但不能返回值。

我的問題是如何返回過濾結果?

回答

0

問題是,您正在執行異步操作,其中API期望同步操作,意味着您啓動了異步操作,而立即返回空的FilterResults,異步操作沒有坐下並等待結果在返回performFiltering方法之前,因此異步操作的結果(在Observer.onNext內)在您已經返回空FilterResults後發生更改。

Filter對象是抽象類,它已經在做這樣做在後臺線程實際工作中,performFilteringmethod invoked in a worker thread的繁重,你應該在publishResults方法處理在UI線程的結果。

該API不完全適合RxJava反應模型,您可以直接在performFiltering調用服務器調用,並在調用工作線程時返回結果。
如果你想RxJava,您可以通過流轉換爲阻斷一個做到這一點並返回結果:

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

編輯:爲什麼你不應該開火publishResults異步請求:

publishResults執行請求將工作,因爲它是爲您在獲得結果(可能會通知適配器)後更新UI而設計的,因此在您在bg中執行請求之後,您將返回到主線程並更新適配器。

但是,它會引入一些錯誤,因爲您沒有被綁定到正確的過濾生命週期,這意味着進度指示將立即消失,並且在您實際在後臺獲取結果時不會顯示,另外,更嚴重的問題,當多個請求被觸發時會引發錯誤,因爲稍後的請求可能在稍後的請求之後到達並且使用舊數據更新適配器。這就是爲什麼你需要遵守過濾器API並在performFiltering以阻塞方式執行請求。

+0

我通過更改請求並將其置於方法中來解決問題@Override protected void publishResults(CharSequence charSequence – matQ

+0

更新答案,並將解釋請求放在'publishResults' – yosriz