Android 如何在使用带有RxJava或Rx2的ApiRest的AutoCompleteTextView适配器中返回FilterResults?
我正在编写一个由ApiRest填充的autocompleteTextView适配器。我正在使用rxJava和改型2。但无法获得筛选结果,因为我不知道如何在异步函数中返回值。这是我的密码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
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());
结果值=数据;