android - ArrayAdapter.getItem java.lang.IndexOutOfBoundsException:索引:1,大小:1
问题描述
我创建了一个 Android 应用程序。我有一个活动,用户输入国家名称,自动完成显示国家列表。该列表是通过 HTTP REST 请求获取的。
这是自动完成的屏幕截图:
它工作正常,但有时(通常当我只输入 2 个字符时)我得到了这个异常,并且从堆栈跟踪中我无法弄清楚问题来自哪里:
2019-11-13 22:13:02.556 18726-18726/it.test.mobile E/it.test.mobil: Invalid ID 0x00000000.
2019-11-13 22:13:02.627 18726-18726/it.test.mobile E/it.test.mobil: Invalid ID 0x00000000.
2019-11-13 22:13:02.768 18726-18726/it.test.mobile E/AndroidRuntime: FATAL EXCEPTION: main
Process: it.test.mobile, PID: 18726
java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
at java.util.ArrayList.get(ArrayList.java:437)
at android.widget.ArrayAdapter.getItem(ArrayAdapter.java:393)
at android.widget.AutoCompleteTextView.buildImeCompletions(AutoCompleteTextView.java:1243)
at android.widget.AutoCompleteTextView.showDropDown(AutoCompleteTextView.java:1203)
at android.widget.AutoCompleteTextView.updateDropDownForFilter(AutoCompleteTextView.java:1086)
at android.widget.AutoCompleteTextView.onFilterComplete(AutoCompleteTextView.java:1068)
at android.widget.Filter$ResultsHandler.handleMessage(Filter.java:285)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
这是我的适配器:
public class CountryAdapter extends ArrayAdapter<Country> {
private Activity activity;
private ArrayList<Country> countryList = new ArrayList<>();
public Resources res;
LayoutInflater inflater;
private String TAG = "CountryAdapter";
/************* CustomAdapter Constructor *****************/
public CountryAdapter(Activity activity, int textViewResourceId, ArrayList<Country> objects, Resources resLocal) {
super(activity, textViewResourceId, objects);
try {
activity = activity;
if (objects != null)
countryList = objects;
res = resLocal;
/*********** Layout inflator to call external xml layout () **********************/
inflater = (LayoutInflater) activity.getSystemService(getContext().LAYOUT_INFLATER_SERVICE);
} catch (Exception e) {
e.printStackTrace();
Logcat.e(TAG, "Errore: " + e.toString());
}
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
try {
return getCustomView(position, convertView, parent);
} catch (Exception e) {
e.printStackTrace();
Logcat.e(TAG, "Errore: " + e.toString());
}
return null;
}
@Override
public int getCount() {
if (countryList != null)
return countryList.size();
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return getCustomView(position, convertView, parent);
}
// This funtion called for each row ( Called data.size() times )
public View getCustomView(int position, View convertView, ViewGroup parent) {
try {
/********** Inflate spinner_rows.xml file for each row ( Defined below ) ************/
View row = inflater.inflate(R.layout.layout_item_country, parent, false);
/***** Get each Model object from Arraylist ********/
return row;
} catch (Exception e) {
e.printStackTrace();
Logcat.e(TAG, "Errore: " + e.toString());
}
return null;
}
}
这是更新适配器的代码:
public class GetCountry extends AsyncTask<Object, Integer, JSONObject> {
private AutoCompleteTextView autocomplete;
@Override
protected JSONObject doInBackground(Object... params) {
try {
JSONParser jParser = new JSONParser(AddFinesActivity.this);
String url = UtilityFunctions.getBaseUrl(AddFinesActivity.this) + Globle.GET_COUNTRY + params[0];
autocomplete = (AutoCompleteTextView) params[1];
Logcat.d(TAG, "doInBackground: url :" + url);
json = jParser.getJSONFromUrl(url, JSONParser.GET, UtilityFunctions.getToken(AddFinesActivity.this), UtilityFunctions.getLanguage());
return json;
} catch (Exception e) {
Logcat.d(TAG, e.getMessage());
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(final JSONObject result) {
if (result != null) {
try {
JSONObject object = result.getJSONObject("_embedded");
countryArray = object.getJSONArray("countries");
//reset the list
countryArrayList.clear();
if (countryArray != null && countryArray.length() > 0) {
for (int i = 0; i < countryArray.length(); i++) {
JSONObject c = countryArray.getJSONObject(i);
countryArrayList.add(Country.getCountryFromJson(c));
}
}
mCountryAdapter = new CountryAdapter(AddFinesActivity.this, R.layout.layout_item_country, countryArrayList, getResources()) {
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
TextView mTextViewName = (TextView) view.findViewById(R.id.text_view_name);
TextView mTextCode = (TextView) view.findViewById(R.id.text_view_code);
ImageView mImageView = (ImageView) view.findViewById(R.id.image_country);
if (countryArrayList != null && countryArrayList.size() > 0) {
mTextViewName.setText("" + countryArrayList.get(position).getName());
mTextCode.setText("" + "(" + countryArrayList.get(position).getAlpha2Code() + ")");
try {
mImageView.setImageDrawable(FlagKit.drawableWithFlag(getContext(), countryArrayList.get(position).getAlpha2Code().toLowerCase()));
} catch (Resources.NotFoundException e) {
//if the flag is not found is not a problem
}
}
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (autocomplete.equals(mEditTextCountry)) {
contactCountryLink = countryArrayList.get(position).getLink().getSelf();
contactCountryName = countryArrayList.get(position).getName();
setContactCountryName(position);
} else if (autocomplete.equals(mEditTextLicensePlateCountry)) {
licensePlateCountryLink = countryArrayList.get(position).getLink().getSelf();
licensePlateCountryName = countryArrayList.get(position).getName();
setLicensePlateCountryName(position);
}
}
});
return view;
}
};
if (mCountryAdapter != null) {
mEditTextCountry.setAdapter(mCountryAdapter);
mEditTextLicensePlateCountry.setAdapter(mCountryAdapter);
mCountryAdapter.notifyDataSetChanged();
}
} catch(Exception e) {
e.printStackTrace();
Logcat.e(TAG, "Errore: " + e.toString());
}
}
}
}
我正在寻找第 393 行,ArrayAdapter.java
但我没有看到它。有什么提示可以理解引发异常的地方吗?
==== 解决方案 ======
我希望它可以帮助
解决方案
很难理解并且需要调试,但我认为它GetCountry
可能会调用多次,您对countryArrayList
fromGetCountry
和有相同的引用adapter
,这意味着countryArrayList
在适配器渲染视图时可能会清除和初始化,并且视图的位置可以是 > fromcountryArrayList
尺寸。因此,也许尝试countryList
在 adaper中隔离,countryList.clear()
而不是countryList.addAll(objects)
在adapter
构造函数中分配使用。
推荐阅读
- angular - 使用 Bootstrap 4 进行布局
- ios - 根目录下的 Codable Handle 动态键
- swift - 如何在 Swift 中设置几个后续的倒数计时器
- c - 矩阵输入期间的分段错误
- angular - 如何将 Base64 Image 从一个组件调用到另一个组件
- android - 当第二次加载 GooglePlaceAutocomplete Fragment 时它崩溃了
- javascript - 在 react-csv 中下载 CSV 后调用函数
- javascript - 当 React 中的 state 不为 null 时更改样式组件
- c# - 比较 List<> 中的两个对象并为它们分配新值
- laravel - Laravel 路由,带参数重定向