我有一个启动异步任务的适配器来查询API。我实现了一个接口,以便从onPostExecute
返回一个返回值,并按照此处列出的示例覆盖适配器中的接口方法:https://stackoverflow.com/a/12575319/5605646。原始代码取自https://stackoverflow.com/a/33428678/5605646,但我想使用asyncTask
来查询API。
由于return语句属于interface overriden方法,我不知道如何将该返回值传递给适配器中的另一个方法。
在适配器类中,DataBufferUtils.freezeAndClose(autocompletePredictions)
返回正确的值,但传递回mResultList
(new Filter()
内部)的内容是null
,因为getAutocomplete
继续前进,直到返回空行。
有谁知道如何将值从DataBufferUtils.freezeAndClose(autocompletePredictions)
传递给mResultList
?
适配器
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);
}
}
接口
public interface AsyncResponse {
public ArrayList<AutocompletePrediction> processFinish((AutocompletePredictionBuffer output);
}
答案 0 :(得分:0)
通过执行以下操作解决了这个问题:
AsyncTask
class getAutocomplete(constraint)
,而不将返回值设置为mResultList processFinish
类中覆盖Adapter
作为自己的方法,而不是嵌套在另一个方法中。mResultList = DataBufferUtils.freezeAndClose(autocompletePredictions)
内设置processFinish
。由于mResultList
是一个全局变量,因此当它在不同的方法中使用时,它已经在其中具有正确的结果。 新适配器:
public class PlaceAutocompleteAdapter extends ArrayAdapter<AutocompletePrediction> implements Filterable,AsyncResponse
{
private static final String TAG = "PlaceAutocompleteAdapter";
private static final CharacterStyle STYLE_BOLD = new StyleSpan(Typeface.BOLD);
// Current results returned by this adapter.
private ArrayList<AutocompletePrediction> mResultList;
// Handles autocomplete requests.
private GoogleApiClient mGoogleApiClient;
// The bounds used for Places Geo Data autocomplete API requests.
private LatLngBounds mBounds;
// The autocomplete filter used to restrict queries to a specific set of place types.
private AutocompleteFilter mPlaceFilter;
//constructor
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;
}
//returns the number of results received in the last autocomplete query
@Override
public int getCount(){
return mResultList.size();
}
// returns an item from the last autocomplete query
@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);
// sets the primary and secondary text for a row.
// note that getPrimaryText() and getSecondaryText() return a CharSequence that may
// contain styling based on the given CharacterStyle
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) {
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 void getAutocomplete(CharSequence constraint) {
if (mGoogleApiClient.isConnected()) {
MyTaskParams params = new MyTaskParams(constraint, mGoogleApiClient, mBounds, mPlaceFilter);
updateSuggestionAsync myTask = new updateSuggestionAsync();
myTask.delegate=this;
myTask.execute(params);
}
}
@Override
public ArrayList<AutocompletePrediction> processFinish(AutocompletePredictionBuffer autocompletePredictions){
Log.i("made it processFinish","made it processFinish");
// 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;
}
mResultList = DataBufferUtils.freezeAndClose(autocompletePredictions);
// Freeze the results immutable representation that can be stored safely.
return mResultList;
}