Android 如何在使用带有RxJava或Rx2的ApiRest的AutoCompleteTextView适配器中返回FilterResults?

Android 如何在使用带有RxJava或Rx2的ApiRest的AutoCompleteTextView适配器中返回FilterResults?,android,rx-java,retrofit2,Android,Rx Java,Retrofit2,我正在编写一个由ApiRest填充的autocompleteTextView适配器。我正在使用rxJava和改型2。但无法获得筛选结果,因为我不知道如何在异步函数中返回值。这是我的密码 public class DiagnosticoAutoCompleteAdapter extends BaseAdapter implements Filterable { ... @Override public Filter getFilter() { Filter filter = new Fil

我正在编写一个由ApiRest填充的autocompleteTextView适配器。我正在使用rxJava和改型2。但无法获得筛选结果,因为我不知道如何在异步函数中返回值。这是我的密码

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;
        }
公共类DiagnosticoAutoCompleteAdapter扩展BaseAdapter实现可过滤{
...
@凌驾
公共过滤器getFilter(){
过滤器过滤器=新过滤器(){
@凌驾
受保护过滤器结果执行过滤(CharSequence CharSequence){
最终FilterResults FilterResults=新的FilterResults();
if(charSequence!=null){
ApiUtils.getAPIServiceDos()
.getDiagnostics(charSequence.toString())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.订阅(新观察员){
@凌驾
认购的公共无效(一次性d){
}
@凌驾
public void onNext(列表值){
//在这里,它显示了尺寸,例如45,以便正确接收值
System.out.println(“tamaño diagnostico::”+value.size());
//在这里,它向我显示了位置0中的对象名及其OK
System.out.println(“contenido diagg…”+value.get(0.getNombre());
filterResults.values=值;
filterResults.count=value.size();
}
@凌驾
公共无效申报人(可丢弃的e){
}
@凌驾
未完成的公共空间(){
}
});
}
//这里我丢失了信息。计数是0
System.out.println(“tamaño de filtered results::”+filterResults.count);
返回过滤器结果;
}
RxJava请求工作正常,但无法返回值


我的问题是如何返回过滤结果???

问题是,您正在执行异步操作,而API需要同步操作,这意味着您正在启动异步操作,而在立即返回空的
FilterResults
时,异步操作不会等待结果再返回它返回到
performFiltering
方法中,因此在返回空
FilterResults
后,异步操作的结果(在
Observer.onNext
中)会发生更改

Filter
对象是一个抽象类,它已经完成了在后台线程上执行实际工作的繁重任务,
performFiltering
,您应该在UI线程的at方法中处理结果

此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;
 }
@覆盖
受保护过滤器结果执行过滤(CharSequence CharSequence){
最终FilterResults FilterResults=新的FilterResults();
if(charSequence!=null){
列表值=ApiUtils.getAPIServiceDos()
.getDiagnostics(charSequence.toString())
.toBlocking()
.first();
System.out.println(“tamaño diagnostico::”+value.size());
System.out.println(“contenido diagg…”+value.get(0.getNombre());
filterResults.values=值;
filterResults.count=value.size();
}
返回过滤器结果;
}
编辑:为什么不应在
publishResults

publishResults
执行请求将起作用,因为它是为您在获得结果后更新UI而设计的(可能会通知适配器),因此在bg中执行请求后,您将返回主线程并更新适配器


但是,它会引入一些错误,因为您没有绑定到正确的筛选生命周期,这意味着进度指示将立即消失,并且在您实际在后台获取结果时不会显示。此外,更严重的问题是,当触发多个请求时,它会导致错误,就像早期的请求一样在晚一个之后到达并用旧数据更新适配器。这就是为什么您需要遵守过滤器API并在
performFiltering

以阻塞方式执行请求。您只需调用notifyDataSetChanged()。它将更新结果。别忘了初始化值和计数

@NonNull
@Override
public Filter getFilter() {
    return new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            final FilterResults results = new FilterResults();
            if (constraint != null) {

                mCompositeDisposable.add(NetworkClient.getRetrofit().create(NetworkInterface.class)
                .getPredictions(MapHelper.makeAutocompleteURL((BaseActivity) context, location, constraint.toString(), Config.SEARCH_RADIUS * 1000))
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread()).subscribeWith(new DisposableObserver<PlaceSerializer>(){
                            @Override
                            public void onNext(PlaceSerializer placeSerializer) {
                                data = new ArrayList<Place>(placeSerializer.getPlaces());
                                results.values = data;
                                results.count = data.size();
                                notifyDataSetChanged();
                            }

                            @Override
                            public void onError(Throwable e) {
                                LogHelper.e(TAG, e.getMessage());
                            }

                            @Override
                            public void onComplete() {

                            }
                        }));

                results.values = data;
                results.count = data.size();
            }
            return results;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            if (results != null && results.count > 0) {
                notifyDataSetChanged();
            } else notifyDataSetInvalidated();
        }
    };
}
@NonNull
@凌驾
公共过滤器getFilter(){
返回新筛选器(){
@凌驾
受保护的筛选器结果性能筛选(CharSequence约束){
最终FilterResults结果=新的FilterResults();
if(约束!=null){
mCompositeDisposable.add(NetworkClient.getReformation().create(NetworkInterface.class)
.getPredictions(MapHelper.makeAutocompleteURL((BaseActivity)上下文、位置、constraint.toString()、Config.SEARCH_RADIUS*1000))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()).subscribeWith(新的DisposableObserver()){
@凌驾
public void onNext(PlaceSerializer PlaceSerializer){
data=newarraylist(placeSerializer.getPlaces());
结果值=数据;