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

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

paint thread

这大概是框架中最重要的一条规则,用来避免你的应用出错。

CrossFly 在 paint thread 上是单线程的

所有 UI 与渲染操作都发生在单一一条线程上 —— 即 paint thread。Main 始终在其上调用 create()、render() 和 resize();每一个 onShow、onPaint、onLayout、触摸 回调以及组件变更都在其中运行。

为什么做这个决定? 简单与正确。只有一条执行线操作 UI,绘制路径上就没有 锁,也没有被争用的共享状态。代价是你必须遵守的一条规则:绝不要从其他线程碰 UI。

标准范式:重活在外,UI 用 onUI 回来

网络、数据库、文件、长时间计算 → 后台线程。要用结果去碰 UI,就用 Component.onUI(...) 回到 paint thread:

new Thread(() -> {
   List<Cliente> dados = repositorio.buscarTudo();   // 繁重工作,后台 thread
   Component.onUI(() -> {                             // 回到 paint thread
      lista.setItems(dados);                          // 现在可以安全操作 UI
      Component.repaint();                             // 请求新的一帧
   });
}).start();

此外还有 Main.runOnPaintThread(Runnable)(以及变体 runOnPaintThreadAndWait(...))用于 在 Component 上下文之外达到同样目的。

违反该规则的典型症状:当你从网络/定时器回调内部“刷新屏幕”时,应用崩溃或 表现异常。修正办法始终是用 onUI(...) 包裹对 UI 的操作。

按需渲染

paint thread 不会持续重绘。只有当有人调用 repaint()(内部为 Gdx.graphics.requestRendering())时才会生成新帧。这能省电 —— 静止的 屏幕不消耗 GPU。

大多数组件的 setter 已经替你调用了 repaint()。需要记住的后果:

  • 改了框架不知道的东西? 你自己调用 repaint()。
  • 动画? 它需要在每一帧保持渲染请求存活(这正是动画器 在 onUpdate 中所做的;参见 值动画)。

onUI

repaint

后台线程
(网络/DB/计算)

paint thread

requestRendering

下一帧
(绘制树)

参见

这个页面有帮助吗?