Вызывается ли метод detach() после метода attach()?

У меня есть простой класс пользовательского интерфейса

public class HelloWorldUI extends UI {

@Override
protected void init(VaadinRequest request) {
    System.out.println("Initialized !");
    final VerticalLayout layout = new VerticalLayout();
    layout.addComponent(new Label("Hello World !"));
    setContent(layout);
}

@Override
public void detach() {
    System.out.println("Detach !");
    super.detach();
}

@Override
public void attach() {
    System.out.println("Attach !");
    super.attach();
}
}

Когда мой пользовательский интерфейс загружается впервые, я вижу выходные данные на своей консоли как

Прикрепить !
Инициализировано !

Это нормально, и это то, что я ожидал. Но когда я обновляю браузер, мои выходные данные консоли были

Прикрепить !
Инициализировано !
Отсоединить !

Удивительно ! Я думаю, что Detach ! может быть создан первым, потому что (как я думаю) при обновлении браузера должен вызываться метод detach(), а attach(), init() должны следовать. Но на самом деле метод detach() будет вызываться после метода attach(). Что не так с моим мышлением?


person Cataclysm    schedule 29.07.2014    source источник
comment
принятый ответ правильный. Я просто хочу отметить, что метод detach вызывается не всегда в каждой ситуации. См. эту публикацию на форуме Анри Сары. Таким образом, вы не должны полагаться на это как на способ очистки ресурсов, закрытия соединений, остановки фоновых потоков и тому подобного.   -  person Basil Bourque    schedule 12.01.2015


Ответы (1)


Обновление браузера = Новый UI экземпляр

Когда вы обновляете окно или вкладку браузера, создается новый экземпляр UI. . Итак, вы видите сообщение о присоединении нового экземпляра UI. Старый экземпляр UI будет отключен позже.

Это поведение по умолчанию в Vaadin 7. Вы можете изменить это поведение с помощью аннотации.

@PreserveOnRefresh

Добавление аннотации @PreserveOnRefresh к UI меняет поведение: Нет нового экземпляра UI не будет создан при обновлении.

Чтобы процитировать документ для этой аннотации:

Отмечает пользовательский интерфейс, который следует сохранить, когда пользователь обновляет окно браузера. По умолчанию при обновлении создается новый экземпляр пользовательского интерфейса, в результате чего любое состояние пользовательского интерфейса, не зафиксированное в URL-адресе или фрагменте URI, отбрасывается. Добавив эту аннотацию в класс пользовательского интерфейса, платформа вместо этого будет повторно использовать текущий экземпляр пользовательского интерфейса при обнаружении перезагрузки.

person Henri Kerola    schedule 29.07.2014
comment
Всегда ли нужна аннотация @PreserveOnRefresh в каждом пользовательском интерфейсе? В каких условиях не следует использовать @PreserveOnRefresh ? Я думаю, что это очень полезно, никакой новый экземпляр пользовательского интерфейса не будет создан при обновлении . - person Cataclysm; 29.07.2014
comment
Это аннотация, поэтому, если вы добавите ее, она будет использоваться для каждого экземпляра пользовательского интерфейса. Если вы действительно хотите, чтобы обновление не создавало новый экземпляр пользовательского интерфейса, всегда используйте аннотации. Некоторые проекты предпочитают именно так, другие предпочитают новый пользовательский интерфейс. - person Jens Jansson; 31.07.2014
comment
Чтобы уточнить, приложение Vaadin 7 может иметь более одного класса UI. . Требуется по крайней мере один пользовательский интерфейс, так как он определяет содержимое для первого окна/вкладки браузера (или области просмотра портлета). Вы можете открывать дополнительные окна/вкладки, в которых тот же или другой UI будет отображаться. Предположительно, вы можете пометить один класс пользовательского интерфейса аннотацией, оставив другой пользовательский интерфейс без аннотаций, каждый из которых будет иметь разное поведение. Предостережения: (а) я не пытался это проверить. (b) Отличающееся поведение сбивает пользователя с толку. - person Basil Bourque; 12.01.2015