I have an adapter that starts an async task to query an API. I implemented an interface in order to get a return value back from onPostExecute
, and override the interface method in the adapter, following the example listed here: https://stackoverflow.com/a/12575319/5605646. The original code is taken from https://stackoverflow.com/a/33428678/5605646, but I want to use asyncTask
for querying the API.
Since the return statement belongs to the interface overriden method, I don't know how to pass that returned value to another method in the adapter.
In the adapter class, DataBufferUtils.freezeAndClose(autocompletePredictions)
returns the correct value, but what's being passed back to mResultList
(inside new Filter()
) is null
, because getAutocomplete
keeps going all the way until the return null line.
Does anyone know how I can pass the value from DataBufferUtils.freezeAndClose(autocompletePredictions)
to mResultList
?
Adapter
public class PlaceAutocompleteAdapter extends ArrayAdapter<AutocompletePrediction> implements Filterable
{
private static final String TAG = "PlaceAutocompleteAdapter";
private static final CharacterStyle STYLE_BOLD = new StyleSpan(Typeface.BOLD);
private ArrayList<AutocompletePrediction> mResultList;
private GoogleApiClient mGoogleApiClient;
private LatLngBounds mBounds;
private AutocompleteFilter mPlaceFilter;
public PlaceAutocompleteAdapter(Context context, GoogleApiClient googleApiClient,LatLngBounds bounds, AutocompleteFilter filter){
super(context, android.R.layout.simple_expandable_list_item_2, android.R.id.text1);
mGoogleApiClient = googleApiClient;
mBounds = bounds;
mPlaceFilter = filter;
}
@Override
public int getCount(){
return mResultList.size();
}
@Override
public AutocompletePrediction getItem(int position){
return mResultList.get(position);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = super.getView(position, convertView, parent);
AutocompletePrediction item = getItem(position);
TextView textView1 = (TextView) row.findViewById(android.R.id.text1);
TextView textView2 = (TextView) row.findViewById(android.R.id.text2);
textView1.setText(item.getPrimaryText(STYLE_BOLD));
textView2.setText(item.getSecondaryText(STYLE_BOLD));
return row;
}
// returns the filter for the current set of autocomplete results
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
//skip the autocomplete query if no constraints are given
if (constraint != null) {
// query the autocomplete API for the search string
mResultList = getAutocomplete(constraint);
if (mResultList != null) {
//the API successfully returned results
results.values = mResultList;
results.count = mResultList.size();
}
}
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results != null && results.count > 0) {
Log.i("notifyDataSetChanged","results are not null");
// The API returned at least one result, update the data.
notifyDataSetChanged();
} else {
Log.i("notifyDataSetInvalid", "results are null");
// The API did not return any results, invalidate the data set.
notifyDataSetInvalidated();
}
}
@Override
public CharSequence convertResultToString(Object resultValue) {
// override this method to display a readable result in the AutocompleteTextView
// when clicked.
if (resultValue instanceof AutocompletePrediction) {
return ((AutocompletePrediction) resultValue).getFullText(null);
} else {
return super.convertResultToString(resultValue);
}
}
};
}
public ArrayList<AutocompletePrediction> getAutocomplete(CharSequence constraint) {
if (mGoogleApiClient.isConnected()) {
MyTaskParams params = new MyTaskParams(constraint, mGoogleApiClient, mBounds, mPlaceFilter);
updateSuggestionAsync myTask = new updateSuggestionAsync(new AsyncResponse(){
@Override
public ArrayList<AutocompletePrediction> processFinish(AutocompletePredictionBuffer autocompletePredictions){
// Confirm that the query completed successfully, otherwise return null
final com.google.android.gms.common.api.Status status = autocompletePredictions.getStatus();
if (!status.isSuccess()) {
Log.i("Error contacting API","Error contacting API");
Toast.makeText(getContext(), "Error contacting API: " + status.toString(),
Toast.LENGTH_SHORT).show();
autocompletePredictions.release();
return null;
}
// Freeze the results immutable representation that can be stored safely.
return DataBufferUtils.freezeAndClose(autocompletePredictions);
}
});
myTask.execute(params);
}
return null;
}
}
AsyncTask
public class updateSuggestionAsync extends AsyncTask<MyTaskParams,Void,AutocompletePredictionBuffer>{
public AsyncResponse delegate = null;
public updateSuggestionAsync (AsyncResponse delegate){
this.delegate = delegate;
}
@Override
protected AutocompletePredictionBuffer doInBackground(MyTaskParams...params){
CharSequence constraint = params[0].constraint;
GoogleApiClient mGoogleApiClient = params[0].mGoogleApiClient;
LatLngBounds mBounds = params[0].mBounds;
AutocompleteFilter mPlaceFilter = params[0].mPlaceFilter;
PendingResult<AutocompletePredictionBuffer> results =
Places.GeoDataApi.getAutocompletePredictions(mGoogleApiClient, constraint.toString(),mBounds,mPlaceFilter);
return results.await(60, TimeUnit.SECONDS);
}
@Override
protected void onPostExecute(AutocompletePredictionBuffer result){
delegate.processFinish(result);
}
}
Interface
public interface AsyncResponse {
public ArrayList<AutocompletePrediction> processFinish((AutocompletePredictionBuffer output);
}