ArrayAdapter.getItem java.lang.IndexOutOfBoundsException: Index: 1, Size: 1

-2

I created an Android application. I've an Activity where the user type the country name and an autocomplete shows a list of countries. The list is get via an HTTP REST request.

This is a screenshot of the autocomplete:

enter image description here

It works fine, but sometimes (usally when I type just 2 chars) I got this exception and from the stacktrace I can't figure out where the problem come from:

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)

This is my adapter:

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

This is the code that updates the adapter:

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


}

}

I was looking for line 393 in ArrayAdapter.java but I don't see it. Any hints to understand the point where the exception is raised?

==== SOLUTION ======

Finally I solved, following this tutorial: https://ridwanolalere.wordpress.com/2015/07/04/how-to-implement-auto-complete-in-android-with-remote-server-data/

I hope it can helps

android
asked on Stack Overflow Nov 13, 2019 by drenda • edited Nov 14, 2019 by drenda

1 Answer

1

It hard to understand and need to debug, but i think it GetCountry may called multiple times, you have same reference to countryArrayList from GetCountry and adapter, that mean that countryArrayList may cleared and initialized while the adapter is rendering the views and the position of the view can be > from countryArrayList size. So maybe try to isolated countryList in adaper instead asigning use countryList.clear() and countryList.addAll(objects) in adapter constructor.

answered on Stack Overflow Nov 13, 2019 by Pavel Poley

User contributions licensed under CC BY-SA 3.0