JamMaster
JamMaster

Reputation: 1454

Array out of bounds in android for no reason

I was debugging my app, having it turned on and suddenly it crashed for no reason. It was running good for a few minutes. Normally this wouldn't be a problem since crashlogs help, but this time the crashlog is useless. Maybe you can see in here why it crashed?

    java.lang.IndexOutOfBoundsException: Invalid index 302, size is 0
        at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
        at java.util.ArrayList.get(ArrayList.java:308)
        at android.widget.ArrayAdapter.getItem(ArrayAdapter.java:337)
        at android.widget.ArrayAdapter.createViewFromResource(ArrayAdapter.java:390)
        at android.widget.ArrayAdapter.getView(ArrayAdapter.java:362)
        at android.widget.AbsListView.obtainView(AbsListView.java:2347)
        at android.widget.ListView.makeAndAddView(ListView.java:1864)
        at android.widget.ListView.fillUp(ListView.java:732)
        at android.widget.ListView.correctTooHigh(ListView.java:1421)
        at android.widget.ListView.fillSpecific(ListView.java:1359)
        at android.widget.ListView.layoutChildren(ListView.java:1651)
        at android.widget.AbsListView.onLayout(AbsListView.java:2151)
        at android.view.View.layout(View.java:15671)
        at android.view.ViewGroup.layout(ViewGroup.java:5038)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
        at android.view.View.layout(View.java:15671)
        at android.view.ViewGroup.layout(ViewGroup.java:5038)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
        at android.view.View.layout(View.java:15671)
        at android.view.ViewGroup.layout(ViewGroup.java:5038)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
        at android.view.View.layout(View.java:15671)
        at android.view.ViewGroup.layout(ViewGroup.java:5038)
        at android.support.v4.widget.DrawerLayout.onLayout(DrawerLayout.java:1043)
        at android.view.View.layout(View.java:15671)
        at android.view.ViewGroup.layout(ViewGroup.java:5038)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
        at android.view.View.layout(View.java:15671)
        at android.view.ViewGroup.layout(ViewGroup.java:5038)
        at com.android.internal.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:494)
        at android.view.View.layout(View.java:15671)
        at android.view.ViewGroup.layout(ViewGroup.java:5038)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
        at android.view.View.layout(View.java:15671)
        at android.view.ViewGroup.layout(ViewGroup.java:5038)
        at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2086)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1843)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1061)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5885)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
        at android.view.Choreographer.doCallbacks(Choreographer.java:580)
        at android.view.Choreographer.doFrame(Choreographer.java:550)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5254)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

This is how I add the adapter to the ListView that i think is affected

    msgs = new CircularArray<Message>(helper.getAllMessages(), MSG_STACK_SIZE);
    if (msgs.getSize() > 0){
        sortedMessages.clear();
        sortedMessages.addAll(msgs.getAllSorted());
        createAdapter();
    }
    setListAdapter(adapter);

sortedMessages is a field that is passed to the adapter's constructor in createAdapter. I also modify that list in a listener that is called from another thread:

    public void onNewMessage(Message msg) {
        msgs.add(msg);
        helper.insertMessage(msg);

        sortedMessages.clear();
        sortedMessages.addAll(msgs.getAllSorted());
        ChatFragment.this.getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                adapter.notifyDataSetChanged();
                setSelection(adapter.getCount() - 1);
            }
        });
    }

Upvotes: 0

Views: 788

Answers (1)

Ahmed Gamal
Ahmed Gamal

Reputation: 338

It seems that the arraylist in the adapter changed while the listview is drawing, you should call notifyDatasetChanges on the adapter wherever the list with the adapter is changed.

Regarding the snippets of your code: you shouldn't update the list from multiple threads, make all the updates to the list from the ui thread and notify the adapter , like that you will avoid changing the list while the adapter getting a view for the list to draw

Upvotes: 1

Related Questions