This page was machine-translated from Portuguese and may contain errors. The Portuguese version is canonical.
Background work
This page consolidates the threading pattern that appears in all the previous ones, from the point of view of whoever writes the heavy work. The “why” is in The paint thread.
The canonical template
new Thread(() -> {
var resultado = trabalhoPesado(); // I/O or CPU — NEVER on the paint thread
meuComponente.onUI(() -> { // re-enters the paint thread
mostrar(resultado); // touch the UI only here
Component.repaint();
});
}).start();
Ways to re-enter the UI:
| Call | Use |
|---|---|
Component.onUI(Runnable) |
from any thread, starting from a component |
Main.runOnPaintThread(Runnable) |
same, outside the context of a component |
Main.runOnPaintThreadAndWait(Runnable) |
same, blocking until it finishes |
React to a UI event on a thread
When a component’s handler must run heavy work, use onActionThread (runs off the paint
thread) and re-enter with onUI:
botao.onActionThread(c -> {
var dados = baixar(); // off the paint thread
c.onUI(() -> lista.setItems(dados)); // back to the UI
});
Timers
For periodic work (polling, watchdog), use the framework timers:
comp.addTimer(1000); // fires a timer event every 1000 ms (handled in the component)
util utilities
ThreadSync— a 2-thread barrier (producer/consumer):start()/start(maxMillis),finished(resultado),getResult(). Useful for waiting on a result from another thread with a timeout.RunnableWith<T>— callback with an argument:void run(T obj). It is the type of the callbacks that deliver a value (e.g.,onErrorofGPSThread).
ThreadSync sync = new ThreadSync();
new Thread(() -> { var r = calcular(); sync.finished(r); }).start();
sync.start(5000); // waits up to 5 s
Object r = sync.getResult();
Best practices
- All blocking I/O (DB, HTTP, GPS, BLE) runs off the paint thread.
- Touch the UI only inside
onUI(...)/runOnPaintThread(...). - Stop threads/timers when leaving the screen (in
onRemove()), otherwise they leak.
Common mistakes
- Touching widgets from a
ThreadwithoutonUI(...)→ erratic behavior/freeze. runOnPaintThreadAndWait(...)called from inside the paint thread (deadlock) — use the non-blocking variant there.- Timers/threads not cancelled when switching screens.
See also
- Concept: The paint thread
- State management · Networking and HTTP
Was this page helpful?Thanks for the feedback!