Temporizador Android actualizando una vista de texto (IU)

Estoy usando un temporizador para crear un cronómetro. El temporizador funciona aumentando un valor entero. Quiero mostrar este valor en la actividad al actualizar constantemente una vista de texto.

Aquí está mi código del servicio donde trato de actualizar la vista de texto de la actividad:

protected static void startTimer() { isTimerRunning = true; timer.scheduleAtFixedRate(new TimerTask() { public void run() { elapsedTime += 1; //increase every sec StopWatch.time.setText(formatIntoHHMMSS(elapsedTime)); //this is the textview } }, 0, 1000); } 

Tengo algún tipo de error sobre la actualización de la interfaz de usuario en el hilo equivocado.

¿Cómo puedo adaptar mi código para cumplir esta tarea de actualizar constantemente la vista de texto?

 protected static void startTimer() { isTimerRunning = true; timer.scheduleAtFixedRate(new TimerTask() { public void run() { elapsedTime += 1; //increase every sec mHandler.obtainMessage(1).sendToTarget(); } }, 0, 1000); } public Handler mHandler = new Handler() { public void handleMessage(Message msg) { StopWatch.time.setText(formatIntoHHMMSS(elapsedTime)); //this is the textview } }; 

El código anterior funcionará …

Nota: Los manejadores se deben crear en su hilo principal para que pueda modificar el contenido de la IU.

En su lugar, debe usar Handler para actualizar la IU cada X segundos. Aquí hay otra pregunta que muestra un ejemplo: ¿ Repite una tarea con un retraso de tiempo?

Su enfoque no funciona porque está tratando de actualizar la interfaz de usuario de la secuencia de comandos no relacionada con la interfaz de usuario. Esto no esta permitido.

 StopWatch.time.post(new Runnable() { StopWatch.time.setText(formatIntoHHMMSS(elapsedTime)); }); 

este bloque de código se basa en Handler, pero no es necesario crear su propia instancia de Handler.

TimerTask implementa Runnable, que lo convertiría en un hilo. No puede actualizar el hilo principal de la interfaz de usuario directamente desde un hilo diferente sin algún trabajo. Una cosa que podría hacer es usar Async Task para crear el temporizador y publicar una actualización cada segundo que actualizará la UI.

Supongo que StopWatch.time es una referencia estática o pública a su TextView. En lugar de hacer esto, debe implementar un BroadcastReceiver para comunicarse entre su temporizador (que se ejecuta desde un hilo separado) y su TextView.

Puede usar la siguiente utilidad:

 /** * Created by Ofek on 19/08/2015. */ public class TaskScheduler extends Handler { private ArrayMap tasks = new ArrayMap<>(); public void scheduleAtFixedRate(final Runnable task,long delay,final long period) { Runnable runnable = new Runnable() { @Override public void run() { task.run(); postDelayed(this, period); } }; tasks.put(task, runnable); postDelayed(runnable, delay); } public void scheduleAtFixedRate(final Runnable task,final long period) { Runnable runnable = new Runnable() { @Override public void run() { task.run(); postDelayed(this, period); } }; tasks.put(task, runnable); runnable.run(); } public void stop(Runnable task) { Runnable removed = tasks.remove(task); if (removed!=null) removeCallbacks(removed); } } 

Entonces, en cualquier parte del código que se ejecute por el subproceso de UI, puedes usarlo simplemente así:

 TaskScheduler timer = new TaskScheduler(); timer.scheduleAtFixedRate(new Runnable() { @Override public void run() { time.setText(simpleDateFormat.format(GamePlay.instance().getLevelTime())); } },1000); 

puedes usar Handler .

este código aumenta un contador cada segundo y muestra y actualiza el valor del contador en un textView .

 public class MainActivity extends Activity { private Handler handler = new Handler(); private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = (TextView) findViewById(R.id.text); startTimer(); } int i = 0; Runnable runnable = new Runnable() { @Override public void run() { i++; textView.setText("counter:" + i); startTimer(); } }; public void startTimer() { handler.postDelayed(runnable, 1000); } public void cancelTimer() { handler.removeCallbacks(runnable); } @Override protected void onStop() { super.onStop(); handler.removeCallbacks(runnable); } } 
  timer.schedule(new TimerTask() { @Override public void run() { //your actions } },1*1000);//1 sec