我有自动完成字段,该字段可从Google Places API获取建议。 在Google Play控制台中,我发现了一些与ArrayAdapter相关的用户异常。
java.lang.NullPointerException:
at android.widget.ArrayAdapter.createViewFromResource (ArrayAdapter.java:445)
at android.widget.ArrayAdapter.getView (ArrayAdapter.java:407)
at fragment.common.PlaceAutocompleteAdapter.getView (PlaceAutocompleteAdapter.java:2)
at android.widget.AbsListView.obtainView (AbsListView.java:3189)
at android.widget.DropDownListView.obtainView (DropDownListView.java:323)
at android.widget.ListView.makeAndAddView (ListView.java:2197)
我的ArrayAdapter的完整代码:
public class PlaceAutocompleteAdapter
extends ArrayAdapter<AutocompletePrediction> implements Filterable {
private final LatLng currentLocation;
private List<AutocompletePrediction> resultList;
private GoogleApiClient googleApiClient;
private LatLngBounds bounds;
private AutocompleteFilter placeFilter;
public PlaceAutocompleteAdapter(final Context context, final GoogleApiClient googleApiClient,
final LatLngBounds bounds, final AutocompleteFilter filter,
final LatLng currentLocation) {
super(context, Layouts.AUTOCOMPLETE_ROW_LAYOUT, Layouts.AUTOCOMPLETE_ROW_ADDRESS);
this.googleApiClient = googleApiClient;
this.bounds = bounds;
this.placeFilter = filter;
this.currentLocation = currentLocation;
}
@Override
public int getCount() {
return resultList != null ? resultList.size() : 0;
}
@Override
public AutocompletePrediction getItem(int position) {
if (position < 0 || getCount() - 1 < position) {
return null;
}
return resultList.get(position);
}
@NonNull
@Override
public View getView(int position, final View convertView, @NonNull final ViewGroup parent) {
View row = super.getView(position, convertView, parent);
AutocompletePrediction item = getItem(position);
if (item == null) {
return row;
}
final TextView addressText = row.findViewById(Layouts.AUTOCOMPLETE_ROW_ADDRESS);
final TextView distanceText = row.findViewById(Layouts.AUTOCOMPLETE_ROW_DISTANCE);
PendingResult<PlaceBuffer> placeResult = Places.GeoDataApi.getPlaceById(googleApiClient, item.getPlaceId());
placeResult.setResultCallback(new ResultCallback<PlaceBuffer>() {
@Override
public void onResult(@NonNull final PlaceBuffer places) {
if (currentLocation != null && places.getStatus().isSuccess() && places.get(0) != null) {
Place place = places.get(0);
double distance = Distance.getDistance(currentLocation, place.getLatLng()) / 1000;
distanceText.setText(getContext().getString(R.string.distanceStats, Parameters.DISTANCE_FORMAT.format(distance)));
}
places.release();
}
}
);
addressText.setText(item.getPrimaryText(null));
return row;
}
@NonNull
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint != null) {
resultList = getAutocomplete(constraint);
if (resultList != null) {
results.values = resultList;
results.count = resultList.size();
}
}
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results != null && results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
@Override
public CharSequence convertResultToString(Object resultValue) {
if (resultValue instanceof AutocompletePrediction) {
return ((AutocompletePrediction) resultValue).getPrimaryText(null);
} else {
return super.convertResultToString(resultValue);
}
}
};
}
private List<AutocompletePrediction> getAutocomplete(CharSequence constraint) {
if (googleApiClient.isConnected()) {
PendingResult<AutocompletePredictionBuffer> results =
Places.GeoDataApi
.getAutocompletePredictions(googleApiClient, constraint.toString(),
bounds, placeFilter);
AutocompletePredictionBuffer autocompletePredictions = results
.await(30, TimeUnit.SECONDS);
final Status status = autocompletePredictions.getStatus();
if (!status.isSuccess()) {
autocompletePredictions.release();
return null;
}
return DataBufferUtils.freezeAndClose(autocompletePredictions);
}
return null;
}
我不明白为什么会在不同的设备和不同的android版本上发生。而且我无法在设备上复制它。