Почему мой цикл всегда выполняется, даже если условия не всегда выполняются?

#java #android #rest #loops #timer

#java #Android #rest #циклы #таймер

Вопрос:

Я создаю приложение для чата, проверяя, есть ли какие-либо новые сообщения, используя вызов REST. По таймеру в одну секунду я проверяю, совпадает ли идентификатор последнего сообщения в списке с последним идентификатором недавно загруженного списка. Если это не тот же идентификатор (есть новые сообщения), обновите recyclerview. Проблема в том, что он продолжает обновляться без каких-либо новых сообщений, и я не уверен, почему. Скорее всего, это простая проблема, хотя я, кажется, не могу ее найти.

Таймер:

 Timer t = new Timer();
        t.schedule(new TimerTask() {
            @Override
            public void run() {
                readMessages(myId, chatId);
            }
        }, 0, 1000);
  

Вызов REST:

 private void readMessages(String myId, String chatId) {

        apiInterface = ApiClient.getClient().create(userApi.class);
        Call<LinkedList<Messages>> call = apiInterface.getMessages(myId, chatId);

        call.enqueue(new Callback<LinkedList<Messages>>() {
            @Override
            public void onResponse(Call<LinkedList<Messages>> call, Response<LinkedList<Messages>> response) {
                mList.clear();
                mList = response.body();
                if (mList2.isEmpty() || mList2.getLast().getId().equals(mList.getLast().getId())) {
                    messageAdapter = new MessageAdapter(ChatActivity.this, mList, Integer.parseInt(myId));
                    recyclerView.setAdapter(messageAdapter);
                    mList2.clear();

                    mList2 = (LinkedList) mList.clone();
                    Toast.makeText(ChatActivity.this, mList2.getLast().getId(), Toast.LENGTH_SHORT).show();

                }
            }

            @Override
            public void onFailure(Call<LinkedList<Messages>> call, Throwable t) {
            }
        });
    }
  

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

1. Я не вижу здесь никакого цикла.

2. в принципе, таймер работает как цикл, и он не всегда должен выполняться через оператор if

3. Я не вижу объявление mList2

4. Следует ли читать вторую половину if-инструкции !mList2.getLast().getId().equals(mList.getLast().getId()) ? То, как он написан в данный момент, означает, что mList2 обновляется, поскольку оба списка имеют одинаковое значение getLast().getId() , тогда как ваше описание подразумевает, что вы хотите обновить, только если идентификаторы не совпадают.

5. Как бы забавно это ни было, я только что заметил это сам с помощью комментария @AlexisDufrenoy. Очень печально, но это было так просто. Спасибо за усилия!

Ответ №1:

Первая часть вашего if заявления такова mList2.isEmpty() (я предполагаю, что mList и mList2 на самом деле одно и то же). Предположение о том, почему каждый вызов onResponse проходит if тест, заключается в том, что список на самом деле пуст. Попробуйте пошаговую отладку и установите точку останова в if строке, чтобы проверить, и если это так, взгляните на свой сервис REST, чтобы понять, почему он отвечает пустым списком.

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

1. При первом тике таймера он пуст, хотя я и предполагал, что так и будет. Каждый раз, когда цикл выполняется, в mList2 содержатся данные.

2. Вы проверили это, чтобы быть уверенным?

3. Я сделал это с всплывающим сообщением. Он всегда показывает последний идентификатор.

4. Итак, mList2 — это старый (из предыдущего цикла) mList. И условием прохождения теста if является либо то, что старый mList пуст, либо то, что текущий mList и последний элемент старого mList имеют одинаковый идентификатор. Итак, вам нужно проверить, какое из этих условий верно. Другого варианта нет.

Ответ №2:

Итак, что именно должно произойти в вашем коде, если условие не будет выполнено?

Если видите, что есть if оператор. И давайте предположим, что мы не будем вдаваться в это, потому что условия не соблюдены. Итак, где оператор else? Что должен делать код, если условия не совпадают? Поскольку в функции больше ничего не нужно делать, элемент управления вернется обратно из функции в таймер.

Вероятно, вы можете попробовать поместить таймер внутри инструкции if, чтобы он выполнялся только при выполнении ваших условий.

Как вы думаете, в этом была проблема?

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

1. Я действительно хотел, чтобы это был бесконечный цикл, который имеет функцию только при наличии нового сообщения. Пытаюсь эмулировать тип firebase приложения для чата.

2. Вы можете попробовать вызвать функцию обратно внутри инструкции else. Таким образом, он может завершиться только в том случае, если выполняется if оператор или происходит сбой.