ListView случайный IndexOutOfBoundsException на Froyo - PullRequest
20 голосов
/ 08 декабря 2011

У меня есть приложение с кучей загрузок, и я получаю много этой ошибки:

 16783         AndroidRuntime  E  java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
 16783         AndroidRuntime  E    at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:257)
 16783         AndroidRuntime  E    at java.util.ArrayList.get(ArrayList.java:311)
 16783         AndroidRuntime  E    at android.widget.HeaderViewListAdapter.isEnabled(HeaderViewListAdapter.java:16
                                  4)
 16783         AndroidRuntime  E    at android.widget.ListView.dispatchDrawWithExcessScroll_Default(ListView.java:3
                                  288)
 16783         AndroidRuntime  E    at android.widget.ListView.dispatchDraw(ListView.java:3029)
 16783         AndroidRuntime  E    at android.view.View.draw(View.java:6743)
 16783         AndroidRuntime  E    at android.widget.AbsListView.draw(AbsListView.java:2549)
 16783         AndroidRuntime  E    at android.view.ViewGroup.drawChild(ViewGroup.java:1640)
 16783         AndroidRuntime  E    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
 16783         AndroidRuntime  E    at android.view.View.draw(View.java:6743)
 16783         AndroidRuntime  E    at android.view.ViewGroup.drawChild(ViewGroup.java:1640)
 16783         AndroidRuntime  E    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
 16783         AndroidRuntime  E    at android.view.ViewGroup.drawChild(ViewGroup.java:1638)
 16783         AndroidRuntime  E    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
 16783         AndroidRuntime  E    at android.view.ViewGroup.drawChild(ViewGroup.java:1638)
 16783         AndroidRuntime  E    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
 16783         AndroidRuntime  E    at android.view.ViewGroup.drawChild(ViewGroup.java:1638)
 16783         AndroidRuntime  E    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
 16783         AndroidRuntime  E    at android.view.ViewGroup.drawChild(ViewGroup.java:1638)
 16783         AndroidRuntime  E    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
 16783         AndroidRuntime  E    at android.view.ViewGroup.drawChild(ViewGroup.java:1638)
 16783         AndroidRuntime  E    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
 16783         AndroidRuntime  E    at android.view.ViewGroup.drawChild(ViewGroup.java:1638)
 16783         AndroidRuntime  E    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
 16783         AndroidRuntime  E    at android.view.ViewGroup.drawChild(ViewGroup.java:1638)
 16783         AndroidRuntime  E    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
 16783         AndroidRuntime  E    at android.view.View.draw(View.java:6743)
 16783         AndroidRuntime  E    at android.view.ViewGroup.drawChild(ViewGroup.java:1640)
 16783         AndroidRuntime  E    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
 16783         AndroidRuntime  E    at android.view.ViewGroup.drawChild(ViewGroup.java:1638)
 16783         AndroidRuntime  E    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
 16783         AndroidRuntime  E    at android.view.View.draw(View.java:6743)
 16783         AndroidRuntime  E    at android.widget.FrameLayout.draw(FrameLayout.java:352)
 16783         AndroidRuntime  E    at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java
                                  :1885)
 16783         AndroidRuntime  E    at android.view.ViewRoot.draw(ViewRoot.java:1407)
 16783         AndroidRuntime  E    at android.view.ViewRoot.performTraversals(ViewRoot.java:1163)
 16783         AndroidRuntime  E    at android.view.ViewRoot.handleMessage(ViewRoot.java:1727)
 16783         AndroidRuntime  E    at android.os.Handler.dispatchMessage(Handler.java:99)
 16783         AndroidRuntime  E    at android.os.Looper.loop(Looper.java:123)
 16783         AndroidRuntime  E    at android.app.ActivityThread.main(ActivityThread.java:4627)
 16783         AndroidRuntime  E    at java.lang.reflect.Method.invokeNative(Native Method)
 16783         AndroidRuntime  E    at java.lang.reflect.Method.invoke(Method.java:521)
 16783         AndroidRuntime  E    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:8
                                  58)
 16783         AndroidRuntime  E    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
 16783         AndroidRuntime  E    at dalvik.system.NativeStart.main(Native Method)

Как вы можете видеть в трассировке стека, нет ни одной строки с моей трассировкой кода вЭто.Чтобы воспроизвести это, я, к счастью, нашел пользователя с Froyo (2.2 p7) и просто прокрутил одну из ListView в коде.После некоторого случайного времени это просто замерзло с этим исключением.Это происходит каждый раз в разное время.

Это ListView с EndlessAdapter позади, просто добавляется все больше и больше строк.Видимо, я получаю эту ошибку, когда делаю «чрезмерную прокрутку», но даже не могу придумать, как это исправить.Воспроизвести его достаточно сложно, но при наличии почти 200 пользователей в сети каждый раз, если они продолжат получать эту ошибку, они больше не будут использовать приложение.

Любая помощь будет принята.

РЕДАКТИРОВАТЬ: была похожая проблема с кем-то еще с EndlessAdapter.http://groups.google.com/group/cw-android/browse_thread/thread/4739ce05742841da/af59c779e99f5e23?lnk=gst&q=index#af59c779e99f5e23

Но это не вина EndlessAdapter.Это вина андроида.

Ответы [ 2 ]

34 голосов
/ 08 декабря 2011

После долгого времени проверки исходного кода Android и непонимания этой ошибки я наконец-то взломал ее.

Проблема возникает с телефонами Samsung, у них другая реализация по функции избыточной прокрутки ив результате возникло исключение, поскольку он пытался выбрать нижний колонтитул / верхний колонтитул за пределами границ (даже если нет представления нижнего колонтитула).

Решение, которое я использовал, не изящное, но оно остановит эту ошибкуснова.

class MyFixedListView extends ListView {
    @Override
    protected void dispatchDraw(Canvas canvas) {
        try {
            super.dispatchDraw(canvas);
        } catch (IndexOutOfBoundsException e) {
            // samsung error
        }
    }
}

Теперь я использую эту реализацию ListView, и ошибка исчезла.

Я действительно надеюсь, что это поможет любому, использующему бесконечные адаптеры.

4 голосов
/ 13 июля 2012

Та же проблема возникает в моем приложении при тестировании на планшетах ICS.Это происходит только тогда, когда у меня есть 11 элементов в списке, когда EndlessAdapter одновременно загружается на 10 элементов.

Это проблема состояния гонки.Проблема связана с обновлением флага keepOnAppending в потоке AsyncTask.В то время как ListView обращается к getCount в потоке пользовательского интерфейса, а для свойстваkekeOnAppending задано значение true, позже, когда он вызывает getView в том же потоке пользовательского интерфейса, и в файле doInBackground уже сбрасывается, и метод kekeOnAppending уже будет сброшен:AppendTask, чтобы он обновлял keepOnAppending в потоке пользовательского интерфейса, только когда новые элементы добавляются в адаптер.

Вот код:

class AppendTask extends AsyncTask<Void, Void, AppendTask.Result> {
    class Result {
        boolean status;
        Exception ex;

        public Result(Exception ex) {
            this.ex = ex;
        }

        public Result(boolean result) {
            this.status = result;
        }
    }

    @Override
    protected AppendTask.Result doInBackground(Void... params) {
        try {
            return new Result(cacheInBackground());
        } catch (Exception e) {
            return new Result(e);
        }
    }

    @Override
    protected void onPostExecute(AppendTask.Result result) {
        if (result.ex == null) {
            appendCachedData();
            keepOnAppending.set(result.status);
        } else {
            keepOnAppending.set(onException(pendingView, result.ex));
        }

        pendingView = null;
        notifyDataSetChanged();
    }
}
...