2010-12-13 17 views
7

ho questo:Come aggiornare un TextView durante il ciclo su Android?

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 


    TextView debugView = (TextView)findViewById(R.id.debugView); 

    for(int i=0;i<100;i++) { 
     try { 
      Thread.sleep(100); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     debugView.setText(Integer.toString(i)); 
    } 

} 

mi aspetterei per aggiornare il testo visualizzare ogni volta attraverso il ciclo quindi vorrei ottenere: 1, 2, 3, ... 99

Invece l'applicazione non fa niente per 10 secondi e poi emette: 99

Suppongo di aver bisogno che TextView si aggiorni durante il ciclo. Sono nuovo nello sviluppo di Android. Qualcuno può dirmi se questo è il modo migliore per farlo?

Il mio obiettivo finale è quello di essere in grado di elaborare campioni audio per costruire un accordatore per chitarra. Sto provando semplicemente a verificare visivamente che l'app risponda ad audio esterno e voglio aggiornare un TextView per dimostrarlo. Si prega di avvisare se c'è un modo migliore per farlo.

+2

Nulla viene visualizzato fino al ritorno onCreate. – Falmarri

risposta

6

Il problema è che si sta eseguendo il loop su onCreate(). Questo sta accadendo sul thread dell'interfaccia utente prima che venga visualizzata l'attività.

Dai uno sguardo allo Activity lifecycle in Android. Mostra che onCreate è solo una delle fasi della creazione di attività. Quello che vorrai fare è eseguire il ciclo su un thread in background e pubblicare la notifica per aggiornare TextView sul thread dell'interfaccia utente usando runOnUiThread. La risposta di Christian mostra come farlo.

Tuttavia, visto che il tuo obiettivo finale è aggiornare il TextView in base a qualche input dell'utente (audio nel tuo caso) non dovrai saltare tutti questi loop per farlo funzionare. L'unica cosa importante è che tu pubblichi le tue chiamate per aggiornare l'interfaccia utente sul thread dell'interfaccia utente, altrimenti otterrai delle eccezioni.

+0

Fuori da oncreate stesso problema. –

8

È meglio utilizzare un timer:

new Timer().schedule(new TimerTask() { 

     @Override 
     public void run() { 
      runOnUiThread(new Runnable() { 
       public void run() { 
        debugView.setText("something"); 
       } 
      }); 
     } 
    }, 0, 100); 

Si noti che sto usando runOnUiThread dal momento che non è possibile modificare la vista da un altro thread che non è quello principale.

+0

Per il mio caso di utilizzo effettivo ho bisogno di essere all'interno di un ciclo poiché sto prelevando campioni audio. Posso già visualizzare l'output usando Log.i(). Sto solo cercando un modo semplice per visualizzare queste informazioni sul dispositivo Android. Non mi interessa quale tipo di interfaccia sia necessario o anche se devo disegnare qualcosa usando una delle interfacce grafiche (se è più veloce del rendering su un TextView).Ti sarei grato se avessi qualche consiglio su come farlo quando sei in loop. Grazie. – chaimp

+0

Solo una nota, il Thread.sleep (100) era solo allo scopo di testare questo in modo che non andasse così veloce che mi manca. In realtà non voglio che ci sia un intervallo di 100 millisecondi. Idealmente dovrebbe andare il più velocemente possibile. – chaimp

+1

In tal caso, utilizzare un AsyncTask. Ci sono molti esempi qui in StackOverflow o su Google. – Cristian

22

Ho avuto lo stesso problema e ho risolto con un gestore:

public class myClass extends Activity{ 

private Handler mHandler; 
private TextView text; 
private int i; 

    @Override 
     public void onCreate(Bundle savedInstanceState) { 
      text = (TextView) findViewById(R.id.textView01); 
      i = 0; 
      mHandler = new Handler(); 
      mHandler.post(mUpdate); 

     } 

private Runnable mUpdate = new Runnable() { 
    public void run() { 

     text.setText("My number: " + i); 
     i++; 
     mHandler.postDelayed(this, 1000); 

    } 
};} 

Con mHandler.post(mUpdate) si chiamano mUpdate che è un Runnable che viene eseguito in un thread diverso in grado di aggiornare l'interfaccia utente. All'interno del metodo run(), invece di creare un ciclo for, che avrebbe lo stesso problema del tuo, devi impostare il testo che desideri con una variabile ausiliaria, incrementarlo e chiamare mHandler.postDelayed(this,updateTime). In questo momento, la vista si aggiorna, e hai il tuo testo sullo schermo, e dopo il tempo che hai specificato (in millisecondi), il mUpdate Runnable verrà chiamato di nuovo e imposta il testo con il prossimo numero, e così sopra.

Spero che aiuti.

1

Invece di usare Handler è possibile passare direttamente Runnable per visualizzare con postDelayed:

public class myClass extends Activity { 

    private TextView text; 
    private int i; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     text = (TextView) findViewById(R.id.textView01); 
     text.postDelayed(mUpdate, 0); 

    } 

    private Runnable mUpdate = new Runnable() { 
     public void run() { 

      text.setText("My number: " + i); 
      i++; 
      text.postDelayed(this, 1000); 

     } 
    }; 
} 
Problemi correlati