Codenameone - Когда использовать callSerially с диалогами? - PullRequest
1 голос
/ 28 мая 2020

В ответе здесь и в разделе 7.2.1 Руководства разработчика Codenameone предлагается вызывать диалоги с помощью callSerially. Я предполагаю, что это означает, что вместо этого:

                    dlg.showDialog();

мы должны использовать:

                Display.getInstance().callSerially(() -> {
                    dlg.showDialog();
                });

Но я замечаю в различных других частях кода Codenameone, что Dialog.shows () не завернуты в callSerially, например ConnectionRequest. java, NetworkManager. java и XFClient. java. Должны ли они использовать callSerially, как было предложено? Если нет, то по каким критериям следует решать, когда использовать callSerially для диалогов, а когда нет?

Справочная информация: я задаю этот вопрос, потому что после реализации сетевой попытки повторения логики c обсуждалось здесь у моих пользователей возникают периодические (и пока невозможно надежно воспроизвести) блокировки приложений, которые, как я подозреваю, могут быть связаны с конфликтом между моим диалоговым окном «Да / Нет» и настраиваемым диалоговым окном сетевых проблем в XFClient (см. Ниже), который может происходить одновременно . Мне интересно, всегда ли я должен использовать callSerially для этих диалогов.

protected void setupConnection(ConnectionRequest req) {
        if (timeout > 0) {
            req.setTimeout(timeout);
        }
        if (readTimeout > 0) {
            req.setReadTimeout(readTimeout);
        }

        // remainder is custom code I added..

        if (silentRetryCount > 0) {     
            req.setSilentRetryCount(silentRetryCount);
        }
        req.addExceptionListener(evt -> {    
            if (evt != null) {
                if (req.getSilentRetryCount() > 0) {
                    //  silentRetryCount--;
                    req.setSilentRetryCount(req.getSilentRetryCount() - 1);
                    //  NetworkManager.getInstance().resetAPN();      // private, not sure if we need this?
                    req.retry();
                    return;
                }
                Exception exc = evt.getError();
                Log.e(exc);
                if (Display.isInitialized() && !Display.getInstance().isMinimized()
                        //                        && Dialog.show("Exception", exc.toString() + ": for URL " + url + "\n" + exc.getMessage(), "Retry", "Cancel")) {
                        && Dialog.show("Network Issue", "Hopefully it is just a bump in the road.  Suggest you retry...", "Retry", "Cancel")) {
                    req.retry();
                }
                // note: ConnectionRequest.handleException has an else block here setting retrying= false and killed=true

            }
        });
    }

Примечание. Добавленный код моделируется после метода handleException в ConnectionRequest. java. Я не мог понять, как добавить блок resetAPN и else, поэтому оставил их. Не уверены, что это была ошибка?

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

1 Ответ

1 голос
/ 29 мая 2020

callSerially для диалогов следует использовать в двух случаях:

  • Вы не в EDT - это требуется
  • Вы находитесь в цепочке событий и хотите текущее событие до гриппа sh. Это сложный крайний случай. Я не буду вдаваться в подробности, так как в данном случае это не применимо.

Первоначально, когда был реализован logi c сетевого менеджера, мы написали код повтора. Мы тогда не заметили нарушения EDT, да и проявлялось оно не так сильно. К сожалению, как и в случае со многими подобными ошибками, сейчас от них трудно избавиться.

Есть и другие решения для этого, но одно из лучших решений - использовать глобальный обработчик сетевых ошибок, что намного ближе к тому, что вы хотите. Этот вопрос охватывает текущее использование для него: Различие guish между ошибками на стороне сервера и проблемами подключения

...