本页面由葡萄牙语机器翻译,可能存在错误。葡萄牙语版本为准。
后台工作
本页面从 编写繁重工作者 的视角出发,整合了在之前所有页面中都出现的线程模型。“为什么” 请参见 绘制线程。
标准模板
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(...)(死锁)—— 在那里请使用 非阻塞的变体。 - 切换屏幕时未取消定时器/线程。
另请参阅
这个页面有帮助吗?感谢你的反馈!