我创建了一个Android应用程序。我有一个“活动”,用户在其中输入国家/地区名称,自动完成功能会显示国家/地区列表。 该列表是通过HTTP REST请求获取的。
这是自动完成功能的屏幕截图:
它工作正常,但是有时(通常当我输入2个字符时)出现此异常,并且从stacktrace中我无法弄清楚问题出在哪里:
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());
}
}
}
}
我正在寻找ArrayAdapter.java
中的393行,但没有看到。
有什么线索可以理解引发异常的地方吗?
====解决方案======
最后,我按照本教程解决了问题:https://ridwanolalere.wordpress.com/2015/07/04/how-to-implement-auto-complete-in-android-with-remote-server-data/
我希望它可以帮助
答案 0 :(得分:1)
很难理解并且需要调试,但是我认为它GetCountry
可能会多次调用,您在countryArrayList
和GetCountry
中对adapter
的引用相同,表示countryArrayList
可以在适配器渲染视图时清除和初始化,并且视图的位置可以大于countryArrayList
。
因此,也许尝试在adaper中隔离countryList
,而不是在countryList.clear()
构造函数中使用countryList.addAll(objects)
和adapter
进行赋值。