如何处理未使用的GWT小部件

时间:2019-05-22 07:24:21

标签: gwt gxt

我正在研究的GWT + GXT UI模块使用面板间的切换来获得不同的视图。非常简单的示例:

mainPanel.add(successPanel);

OR

mainPanel.add(errorPanel);

我注意到,如果errorPanel永远不会被使用(附加),它将永远不会被丢弃。

我知道将两个UI元素都添加到DOM中并切换可见性应该可以达到相同的结果并提供适当的GC,但是重构所有操作可能会带来很多其他问题。

我尝试了以下方法:

  • 将未使用的元素附加到RootPanel,然后调用widget.removeFromParent()。
  • 将未使用的元素添加到活动的DOM元素中之前
  • 调用DOM.setEventListener(widget.getElement(),null)。
  • 制作一个可提供removeMethod的助手类,而与附件状态无关:
  public static void removeWidget(Widget w) {
    if (w.getParent() == null) {
      RootPanel.get().add(w);
      if (RootPanel.isInDetachList(w)) {
        RootPanel.detachNow(w);
      } else {
        try {
          // onUnload() gets called *before* everything else (the opposite of
          // onLoad()).
          w.onUnload();
          AttachEvent.fire(w, false);
        } catch (Exception e) {
          // ??? throws "Should only call onDetach when the widget is attached to the browser's document"
        } finally {
          // Put this in a finally, just in case onUnload throws an exception.
          try {
            w.doDetachChildren();
          } catch (Exception e) {
            // ???
          } finally {
            // Put this in a finally, in case doDetachChildren throws an exception.
            DOM.setEventListener(w.getElement(), null);
            //w.attached = false; // ??
          }
        }
      }
    } else if (w instanceof HasWidgets) {
      ((HasWidgets) w).remove(w);
    } else if (w != null) {
      throw new IllegalStateException("This widget's parent does not implement HasWidgets");
    }

  }

这些方法都不可靠。有什么方法可以将不需要的小部件标记为不需要的,并让GWT处理所有处置,包括其子级吗?

以某种方式与我的问题有关,除了“自己动手”的跟踪器之外,还有什么方法可以弄清哪些小部件/类没有被处置?

1 个答案:

答案 0 :(得分:3)

GWT窗口小部件没有“释放”功能-只有附加/分离。如果该窗口小部件是分离的(或从不连接),则在没有引用的情况下,正常的垃圾回收将起作用。

如果您将其保留为“附加”模式,但实际上删除了对其的所有引用(手动将其从DOM中删除,或者手动触发附加而不将其实际放入DOM中,等等),它将泄漏某些浏览器(古老的Firefox,IE6-9或10等)。

您执行附加和分离的步骤与开始时从未附加其效果相同。您的泄漏不在其他地方,而是在GWT Widget的生命周期中。 GWT中没有“处置”-只要不实际附加,普通的GC就足够了。