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