Android e Bluetooth (5)

luca 04/05/2014 7

Se avete provato l’app presentata nel tutorial precedente, forse vi sarete accorti di un difetto: mentre viene stabilita la connessione Bluetooth con il dispositivo e viene inviato il messaggio, l’interfaccia grafica dell’applicazione non risponde. Il motivo è semplice: molti metodi utilizzati sono blocking, ovvero fermano l’esecuzione del processo che li chiama finché non ottengono un risultato (o un timeout).

Se ad esempio utilizziamo il metodo read() per leggere dati da un socket, tale metodo fermerà l’esecuzione del processo finché un dato non è disponibile!

Per risolvere il problema, dobbiamo creare una applicazione multitasking, ovvero formata da più processi con esecuzione indipendente.

Threads e GUI

Per semplificare, una applicazione può essere formata da uno o più processi (thread), eseguiti dal S.O. Android in parallelo. Le applicazioni più semplici, come quelle degli esempi precedenti, hanno un unico thread, chiamato main thread. Questo thread ha, tra gli altri, il compito di gestire i componenti (testo, immagini, pulsanti…) che compongono l’interfaccia (GUI) dell’applicazione.

La prima regola da tenere sempre in mente quando si lavora ad applicazioni multithread è infatti che solo il main thread può modificare l’intefaccia grafica:

Questa regola da spesso problemi ai programmatori: pensate al caso in cui un secondo thread riceve dati dal socket Bluetooth: probabilmente alla ricezione di determinati comandi, l’interfaccia grafica deve essere aggiornata di conseguenza…

La soluzione normalmente suggerita è di chiedere al thread principale di effettuare tale aggiornamento… io invece voglio mostrarvi un approccio alternativo, che si basa sull’uso dell’oggetto AsyncTask.

AsyncTask

L’oggetto AsyncTask è stato pensato per gestire in maniera semplice dei tasks che devono eseguiti in background e che devono interagire con l’intefaccia grafica dell’applicazione.

Il suo vantaggio è che, in maniera trasparente per il programmatore, ha alcuni metodi che vengono eseguiti nel GUI (main) thread e altri che invece vengono eseguiti in un thread separato.

Il programmatore può quindi sfruttare i metodi eseguiti nel GUI thread per aggiornare l’interfaccia e quelli nel secondo thread per le operazioni in background (ad es. per ricevere/inviare dati attraverso il socket):

Vediamo i metodi nel dettaglio:

  • onPreExecute() – GUI – eseguito appena prima dell’inizio delle attività in background, può essere utile per visualizzare un avviso (animazione, messaggio…) che l’operazione richiesta è in esecuzione
  • doInBackground() – background – metodo principale che viene eseguito in un thread separato
  • publishProgress() – background – metodo, normalmente chiamato da doInBackground(), che serve per notificare un “progresso” nell’esecuzione del task
  • onProgressUpdate() – GUI – metodo, chiamato da publishProgress(), che può aggiornare l’intefaccia grafica ricevendo il “progresso” del task in background
  • onPostExecute() e onCancelled() – GUI – metodi eseguiti alla fine del task (o alla sua cancellazione)

Nella prossima pagina vedremo come mettere tutto questo in pratica in una applicazione Android…

Pagine: 1 2

7 Comments »

  1. jmv 05/05/2014 at 16:48 - Reply

    very good luca, thanks!
    waiting the next.

  2. Matthew 07/09/2014 at 07:38 - Reply

    Hi Luca,
    Android coding is not simple.

    I have developed pfodApp that does all the Android stuff for you. Lets you display menus and screens from your Arduino by means of simple text strings.
    Take a look at http://www.pfod.com.au for all the details.

  3. norm 07/03/2015 at 11:53 - Reply

    Hi Luca

    Great example, thank you !

    Would you recommend using this method to send/receive bluetoothdata from different activities within an app ??

    If so how would you modify your code to work ?

    • luca 08/03/2015 at 13:32 - Reply

      Hi! My suggestion is to have only ONE “manager” that performs all the communication tasks and dispatches the messages to the different activities

  4. Mauro 20/06/2016 at 13:22 - Reply

    GRANDE GIOVE !!!

    MITICO LUCA !
    Funziona e non ho più gli errori in Eclipse.
    Questo era lo scoglio da superare per avere il punto di partenza
    interattivo con la macchina che monta l’ HC-06.
    Ora è una passeggiata nel parco !

    Grazie.

  5. Mauro 20/06/2016 at 13:54 - Reply

    Riciao.

    Non ho capito come mai l’ XML per l’UI è
    nel Fragment_main anziché nel activity_main
    e funziona ugualmente….

    Cos’è che non so ?

    Grazie

    Mauro

  6. Mauro 29/06/2016 at 10:17 - Reply

    Ciao Luca !

    Non riesco a cancellare il contenuto di tvResponse. Ho implementato un pulsante per pulire il contenuto dalle risposte della macchina via BT ma vorrei che a piacimento si potesse cancellare.

    Ti ringrazio per la collaborazione.

    Mauro

Leave A Response »

Questo sito usa i cookie per poterti offrire una migliore esperienza di navigazione maggiori informazioni

Questo sito utilizza i cookie per fonire la migliore esperienza di navigazione possibile. Continuando a utilizzare questo sito senza modificare le impostazioni dei cookie o clicchi su "Accetta" permetti al loro utilizzo.

Chiudi