跳到内容
CrossFly 是 100% 开源在 GitHub 关注我们
CrossFlyCrossFly
开始使用

本页面由葡萄牙语机器翻译,可能存在错误。葡萄牙语版本为准。

生命周期

CrossFly 的生命周期分为三个层级:应用、窗口(屏幕)和组件。

层级 1 —— 应用:启动引导(Main)

Main 是 libGDX 的 ApplicationListener。当平台启动时,libGDX 在 paint thread 上调用 Main.create(),随后 Main:

  1. 检测平台并初始化运行时和设备配置;
  2. 解析主窗口的名称(来自 classname 参数或 getMainWindow());
  3. 通过反射实例化该窗口(Class.forName(...) → newInstance())并调用其 onShow()。

在此之后,libGDX 会调用 render()(在每个渲染帧)和 resize() —— 始终在 paint thread 上。

层级 2 —— 窗口:onShow()

每个屏幕都是 Window 的子类,它在 onShow() 中搭建自己的 UI(并调用 super.onShow()):

public class TelaHome extends Window {
   @Override public void onShow() throws Exception {
      super.onShow();
      setLayout(new VerticalLayout());
      add(LAY_AUTO, new Label("Início"));
   }
}

为什么用 onShow() 而不是构造函数? 在构造函数中,边界和层级尚未 就绪 —— Screen.width/height 和窗口尺寸只有之后才有效。过早搭建 UI 会导致测量错误。(窗口栈与导航见 窗口栈。)

层级 3 —— 组件:onAdd(firstTime) / onRemove()

当一个组件进入树时,框架会调用 onAdd(boolean firstTime);当它离开时,调用 onRemove()。你就在这里初始化并释放资源:

public class Relogio extends Component {
   private Timer timer;
   @Override public void onAdd(boolean firstTime) throws Exception {
      super.onAdd(firstTime);
      if (firstTime) timer = iniciarTimer();   // 只应存在一次的资源
   }
   @Override public void onRemove() {
      if (timer != null) timer.cancel();        // 退出时务必释放
      super.onRemove();
   }
}

firstTime 区分了什么? 一个组件可以被添加、移除,再重新添加。 firstTime == true 只在第一次成立 —— 用它来做不应重复的初始化。onRemove() 是 清理的对应方:取消定时器、监听器、光标。

通用规则:不要在构造函数中初始化 UI/资源。使用 onShow()(窗口)和 onAdd(firstTime)(组件),在那里边界和层级已经有效。

Main.create() (paint thread)

通过反射实例化 MainWindow

Window.onShow() — 构建 UI

Component.onAdd(firstTime) — 每个子节点

存活: onLayout / onPaint / 事件

Component.onRemove() — 释放资源

参见

这个页面有帮助吗?