2017-07-29 54 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

相关问题