2010-12-13 12 views
7

tengo esto:¿Cómo actualizar un TextView mientras se repite en 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)); 
    } 

} 

yo esperaría que se actualice el texto ver cada vez a través del bucle así que me gustaría tener: 1, 2, 3, ... 99

En lugar de la aplicación no hace nada durante 10 segundos y luego muestra: 99

Supongo que necesito TextView para actualizar durante el ciclo. Soy nuevo en el desarrollo de Android. ¿Alguien puede decirme si esta es la mejor manera de lograr esto?

Mi objetivo final es poder procesar muestras de audio para construir un afinador de guitarra. Intento simplemente verificar visualmente que la aplicación está respondiendo a audio externo y quiero actualizar un TextView para demostrar eso. Por favor, indique si hay una mejor manera de hacerlo.

+2

No se visualiza nada hasta que vuelva alcrear. – Falmarri

Respuesta

6

Su problema es que está ejecutando su ciclo en onCreate(). Esto sucede en el hilo de la interfaz de usuario antes de que se muestre tu actividad.

Eche un vistazo a Activity lifecycle en Android. Muestra onCreate es solo una de las etapas en la creación de la actividad. Lo que querrá hacer es ejecutar el ciclo en un hilo de fondo y publicar la notificación para actualizar el TextView en el hilo de UI usando runOnUiThread. La respuesta de Christian muestra cómo hacer esto.

Sin embargo, dado que su objetivo final es actualizar el TextView en función de la entrada del usuario (audio en su caso), no tendrá que pasar por todos estos bucles para que funcione. Lo único importante es que publiques tus llamadas para actualizar la UI en el hilo de UI, de lo contrario obtendrás excepciones.

+0

Fuera de oncreate mismo problema. –

8

Es mejor que usar un temporizador:

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

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

en cuenta que estoy usando runOnUiThread ya que no puede modificar una vista desde otro hilo que no es el principal.

+0

Para mi caso de uso real, necesito estar dentro de un bucle ya que estoy extrayendo muestras de audio. Ya puedo mostrar la salida usando Log.i(). Solo estoy buscando una forma sencilla de mostrar esta información en el dispositivo Android. No me importa qué tipo de interfaz es necesaria o incluso si tengo que dibujar algo usando una de las UI de gráficos (si es más rápido que renderizar en un TextView).Le agradecería si tuviera algún consejo sobre cómo hacer esto cuando esté en bucle. Gracias. – chaimp

+0

Solo una nota, el Thread.sleep (100) solo fue con el propósito de probar esto, por lo que no fue tan rápido que lo extrañé. En realidad, no quiero que haya un intervalo de 100 milisegundos. Idealmente debería ir lo más rápido posible. – chaimp

+1

En ese caso, use una AsyncTask. Hay muchos ejemplos aquí en stackoverflow o en Google. – Cristian

22

que tenían el mismo problema y lo resolvió con un manejador:

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) que llaman mUpdate que es un Ejecutable que se ejecuta en un hilo diferente que puede actualizar la interfaz de usuario. Dentro del método run(), en lugar de crear un bucle for, que tendría el mismo problema que el tuyo, configura el texto que deseas con una variable auxiliar, increméntalo y llama al mHandler.postDelayed(this,updateTime). En este momento, la vista se actualiza, y usted tiene su texto en la pantalla, y después del tiempo que ha especificado (en milisegundos), Runnable mUpdate se volverá a llamar y establece el texto con el siguiente número, y así en.

Espero que ayude.

1

En lugar de utilizar Handler es posible pasar directamente Ejecutable para ver 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); 

     } 
    }; 
} 
Cuestiones relacionadas