Aggiornare frequentemente una TextView all’interno di un ciclo

Il problema
Come aggiornare una TextView all’interno di un ciclo o più in generale come aggiornare frequentemente un elemento UI di una Activity.
Considera il seguente esempio:

  1. crea un progetto Android senza acitvity iniziale
  2. modifica il file AndroidManifest.xml
  3. crea il file res/layout/activity_main.xml
  4. crea il file eu/lucazanini/updateui/MainActivity.java

Il risultato aspettato è quello di aggiornare di continuo per 5 secondi la TextView secondo l’orario della device, invece il risultato osservato è quello di un unico aggiornamento alla fine.

La causa
Nel LogCat si legge il messaggio “Skipped […] frames! The application may be doing too much work on its main thread.”; il messaggio è chiaro: troppe operazioni per il thread principale conosciuto anche come UI thread.
Un primo tentativo per risolvere il problema potrebbe essere quello di chiamare il metodo updateUI da un altro thread come nell’esempio seguente:

ma l’applicazione va in crash alla linea 45 lanciando l’eccezione “android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.”.
Infatti non è possibile accedere a una View da threads che non siano quello principale.
Quindi la questione è come accedere a una View senza occupare troppe risorse del UI thread?

La prima soluzione: la classe Handler
Una istanza di Handler è associata al thread in cui è stato creata, in questo caso il thread principale, e un secondo thread (separateThread) utilizza l’Handler per inviare un Message al thread principale.

La seconda soluzione: la classe AsyncTask
In questo esempio la classe interna MyAsyncTask estende la classe astratta AsyncTask, e sovrascrive il metodo doInBackground che esegue il calcolo e con l’istruzione publishProgress chiama il metodo onProgressUpdate che esegue l’aggiornamento della TextView.
Spesso l’aggiornamento della TextView è richiesto dopo che è stato completato il metodo doInBackground, in tal caso il codice per aggiornare la TextView può essere inserito nel metodo onPostExecute.

2 risposte a “Aggiornare frequentemente una TextView all’interno di un ciclo”

  1. I am curios to know if this code works. I am running something very similar but I am getting the error “Only the original thread that created a view hierarchy can touch its views”. After reading many posts I have seen people usually set views on the UI thread instead of on the async task and use async tasks to run other time consuming code.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.