ArrayList iterator.remove () внутри AsyncHttpClient генерирует исключение IllegalStateException - PullRequest
0 голосов
/ 03 января 2019

Я пытаюсь сделать HttpClient POST для отправки каждого элемента ArrayList один за другим на сервер. Вот некоторые фрагменты моих кодов:

    ArrayList<String> testArrayList = new ArrayList<>();
    testArrayList.add("Item 1");
    testArrayList.add("Item 2");

    final Iterator<String> iterator = testArrayList.iterator();

     while(iterator.hasNext()){

            for(int i = 0; i<testArrayList.size(); i++){
                 currentContent += "| " + testArrayList.get(i) + " | ";
            }

        currentItem = iterator.next();  

        final String url = "some url here"

        RequestParams params = new RequestParams();
        params.add("item_name", currentItem);

        new AsyncHttpClient().post(url, params, new AsyncHttpResponseHandler( {
            @Override
            public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {

                Toast.makeText(context, "Removing..", Toast.LENGTH_SHORT).show();
                iterator.remove();

            }

            @Override
            public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {

            }
        });
    }

Проблема в iterator.remove() всегда вызовет исключение IllegalStateException. Это не происходит, если AsyncHttpClient не участвует. Что я пробовал:

  • Я пытался поместить iterator.next() в onSuccess() (в этом случае не добавлено RequestParams, просто чтобы попробовать), но это приложение зависает и не отвечает. (В моем случае я на самом деле хотел бы оставить его снаружи onSuccess(), потому что из итератора где я найду свой RequestParams)
  • Я искал похожие вопросы. Большинство проблем вызвано тем, что вы не позвонили iterator.next() до iterator.remove(). У меня есть, но мой код все еще не работает. Другой частой причиной было бы то, что iterator.remove() вызывается во внутреннем цикле, но это не мой случай.

Я застрял в этой проблеме несколько недель. Пожалуйста, помогите мне.

Ответы [ 2 ]

0 голосов
/ 03 января 2019

Вы можете использовать рекурсию, где метод вызывает себя.

 ArrayList<String> testArrayList = new ArrayList<>();
        testArrayList.add("Item 1");
        testArrayList.add("Item 2");    


    void submitItem(ArrayList<String> items){

    final String url = "some url here"

    RequestParams params = new RequestParams();
    params.add("item_name", currentItem);

 new AsyncHttpClient().post(url, params, new AsyncHttpResponseHandler( {
            @Override
            public void onSuccess(int statusCode, Header[] headers, byte[] 
             responseBody) {


                items.remove(0);
                Toast.makeText(context, "Removing..", Toast.LENGTH_SHORT).show();
                if(ites.size() > 0) submitItem(items);

            }

            @Override
            public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {

            }
        });

}
0 голосов
/ 03 января 2019

С https://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html#remove--:

IllegalStateException - если следующий метод еще не был вызван или метод remove уже был вызван после последнего вызова следующего метода

Вы вызываете iterator.remove () из обратного вызова, переданного AsyncHttpClient. Этот клиент выполняется в другом Thread, и обратный вызов будет выполнен в основном пользовательском интерфейсе Thread. Однако у вас нет никаких гарантий о порядке исполнения здесь.

Итак, что, вероятно, случается со временем: 1) iterator.next() (из цикла while)
2) сообщение сработало
3) iterator.next() (из цикла while)
4) сообщение сработало
5) первый обратный звонок iterator.remove()
6) второй обратный вызов iterator.remove()

Вы можете попытаться проверить это, поместив операторы журнала перед вызовом next и удалить.

...