Исключение IndexOutOfBoundException при чтении из курсора

#android #android-cursorloader

#Android #android-cursorloader

Вопрос:

Я пытаюсь использовать CursorLoader , но продолжаю получать IndexOutOfBounds ошибку при чтении из Cursor . Соответствующие строки ошибок из Logcat:

 at com.codephillip.app.busticket.SelectRouteFragment.onLoadFinished(SelectRouteFragment.java:96)
at com.codephillip.app.busticket.SelectRouteFragment.onLoadFinished(SelectRouteFragment.java:28) 
  

Это класс fragment:

 public class SelectRouteFragment extends Fragment implements MaterialSpinner.OnItemSelectedListener, LoaderManager.LoaderCallbacks {

    private static final String TAG = SelectRouteFragment.class.getSimpleName();
    private MaterialSpinner destSpinner;
    private MaterialSpinner sourceSpinner;
    private Button selectButton;
    private String destination;
    private String source;

    public SelectRouteFragment() {


    }

    public static SelectRouteFragment newInstance() {
        return new SelectRouteFragment();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_select_route, container, false);
        destSpinner = rootView.findViewById(R.id.dest_spinner);
        sourceSpinner = rootView.findViewById(R.id.source_spinner);

        destSpinner.setOnItemSelectedListener(this);
        sourceSpinner.setOnItemSelectedListener(this);

        selectButton = rootView.findViewById(R.id.select_button);
        selectButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (source.equals(destination)) {
                    Toast.makeText(getContext(), "Choose a different Destination", Toast.LENGTH_SHORT).show();
                } else {
                    Intent intent = new Intent(getContext(), BookActivity.class);
                    intent.putExtra(Utils.SOURCE, source);
                    intent.putExtra(Utils.DESTINATION, destination);
                    getActivity().startActivity(intent);
                }
            }
        });
        return rootView;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        getLoaderManager().initLoader(2, null, this);
    }

    @Override
    public Loader onCreateLoader(int id, Bundle args) {
        return new CursorLoader(getContext(), LocationsColumns.CONTENT_URI, null, null, null, null);
    }

    @Override
    public void onLoadFinished(Loader loader, Cursor data) {
        Log.d(TAG, "onLoadFinished: started");
        LocationsCursor cursor = new LocationsCursor(data);
        List locations = new ArrayList<>();
        if (cursor.moveToFirst()) {
            do {
                locations.add(cursor.getName());
            } while (cursor.moveToNext());
        }

        // Set default route values
        source = locations.get(0);
        destination = locations.get(0);

        ArrayAdapter dataAdapter = new ArrayAdapter(getContext(), android.R.layout.simple_expandable_list_item_1, locations);
        dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        sourceSpinner.setAdapter(dataAdapter);
        destSpinner.setAdapter(dataAdapter);
    }

    @Override
    public void onLoaderReset(Loader loader) {

    }

    @Override
    public void onItemSelected(MaterialSpinner view, int position, long id, Object itemObject) {
        Snackbar.make(view, "Clicked "   itemObject.toString(), Snackbar.LENGTH_LONG).show();
        String item = itemObject.toString();
        Log.d(TAG, "onItemSelected: "   item);

        if (view.getId() == destSpinner.getId()) {
            Log.d(TAG, "onItemSelected: clicked dest");
            destination = item;
        } else {
            Log.d(TAG, "onItemSelected: clicked source");
            source = item;
        }
    }
}
  

Любая помощь в понимании проблемы была бы высоко оценена.

Комментарии:

1. Исключение IndexOutOfBoundException возникает при размере массива 1 и получении элемента из позиции массива 1.

2. Изменен заголовок, чтобы лучше выразить проблему. Отформатировал строки Logcat и удалил импорт из класса, поскольку они были бесполезны. Добавлено описание, а также заявление с благодарностью.

Ответ №1:

Я предполагаю, что проблема возникает здесь:

 source = locations.get(0);
destination = locations.get(0);
  

Если cursor пусто, locations также будет пусто, а затем, locations.get(0) выдаст исключение.

Вы должны проверить, не пустое ли местоположение.

 if(locations.size() > 0) {
    ...
}
  

Комментарии:

1. Я согласен с ответом @ W0rmH0le