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

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

后台工作

本页面从 编写繁重工作者 的视角出发,整合了在之前所有页面中都出现的线程模型。“为什么” 请参见 绘制线程。

标准模板

new Thread(() -> {
   var resultado = trabalhoPesado();        // I/O 或 CPU — 绝不在 paint thread 上
   meuComponente.onUI(() -> {               // 重新进入 paint thread
      mostrar(resultado);                    // 仅在此处操作 UI
      Component.repaint();
   });
}).start();

返回 UI 的方式:

调用 用途
Component.onUI(Runnable) 从任意线程,基于某个组件
Main.runOnPaintThread(Runnable) 同上,但不在某个组件的上下文中
Main.runOnPaintThreadAndWait(Runnable) 同上,阻塞 直到完成

在线程中响应 UI 事件

当某个组件的处理程序需要运行繁重工作时,使用 onActionThread(在绘制线程之外运行), 再通过 onUI 返回:

botao.onActionThread(c -> {
   var dados = baixar();                    // 不在 paint thread 中
   c.onUI(() -> lista.setItems(dados));     // 回到 UI
});

定时器

对于周期性工作(轮询、看门狗),使用框架的定时器:

comp.addTimer(1000);   // 每 1000 ms 触发一次计时器事件(由组件处理)

util 中的工具

  • ThreadSync —— 2 个线程 的屏障(生产者/消费者):start()/start(maxMillis), finished(resultado)、getResult()。用于带超时地等待另一个线程的结果。
  • RunnableWith<T> —— 带参数的回调:void run(T obj)。它是那些 传递值的回调的类型(例如:GPSThread 的 onError)。
ThreadSync sync = new ThreadSync();
new Thread(() -> { var r = calcular(); sync.finished(r); }).start();
sync.start(5000);                 // 最多等待 5 秒
Object r = sync.getResult();

最佳实践

  • 所有 阻塞式 I/O(DB、HTTP、GPS、BLE)都在绘制线程 之外 运行。
  • 仅 在 onUI(...)/runOnPaintThread(...) 内部操作 UI。
  • 离开屏幕时(在 onRemove() 中)停止线程/定时器,否则会泄漏。

常见错误

  • 从 Thread 中未经 onUI(...) 操作控件 → 行为异常/卡死。
  • 在绘制线程 内部 调用 runOnPaintThreadAndWait(...)(死锁)—— 在那里请使用 非阻塞的变体。
  • 切换屏幕时未取消定时器/线程。

另请参阅

这个页面有帮助吗?