Temporizador Android actualizando una vista de texto (UI)
Estoy usando un temporizador para crear un cronómetro. El temporizador funciona aumentando un valor entero. Quiero mostrar este valor en la actividad actualizando constantemente una vista de texto.
Aquí está mi código del servicio en el que intento actualizar el texto de la actividad:
- ¿Temporizador Android? ¿Cómo?
- Android relanzando temporizadores después de que se cancelen
- Android: EditText pierde foco cuando se llama a setText
- Android equivalente de setTimeout y clearTimeout de javascript?
- ¿Cómo hacer un temporizador simple sin nueva clase en Android?
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 acerca de la actualización de la interfaz de usuario en el hilo equivocado.
¿Cómo puedo adaptar mi código para realizar esta tarea de actualización constante de la vista de texto?
Gracias.
- Android - Cómo detener y detener el temporizador
- Mostrar temporizador en texto contiene días, horas, minutos y segundos en android
- Detener el temporizador y continuar
- Android Timer: postDelayed vs. schedule
- Android: ejecuta un hilo repetidamente dentro de un temporizador
- OnPause / onResume problemas de actividad
- Android: Acceso al elemento de interfaz de usuario desde el subproceso del temporizador
- Enviar notificación una vez por semana
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 } };
Por encima del código funcionará …
Nota: Los manejadores deben crearse en el hilo principal para poder modificar el contenido de la interfaz de usuario.
Debe utilizar Handler
lugar para actualizar la interfaz de usuario cada X segundos. Aquí hay otra pregunta que muestra un ejemplo: ¿ Repite una tarea con un retardo de tiempo?
Su enfoque no funciona porque está intentando actualizar la interfaz de usuario desde un subproceso no perteneciente a 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 necesita crear su propia instancia de Handler.
TimerTask implementa Runnable, lo que lo convertiría en un hilo. No puede actualizar el subproceso de interfaz de usuario principal directamente desde un subproceso diferente sin algún trabajo. Una cosa que podría hacer es utilizar Async Task para crear el temporizador y publicar una actualización cada segundo que actualizará la interfaz de usuario.
Estoy asumiendo StopWatch.time
es una cierta 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 utilizar la siguiente utilidad:
/** * Created by Ofek on 19/08/2015. */ public class TaskScheduler extends Handler { private ArrayMap<Runnable,Runnable> 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); } }
A continuación, en cualquier parte del código que se ejecuta por el subproceso UI, puede utilizarlo de la siguiente manera:
TaskScheduler timer = new TaskScheduler(); timer.scheduleAtFixedRate(new Runnable() { @Override public void run() { time.setText(simpleDateFormat.format(GamePlay.instance().getLevelTime())); } },1000);
Puede utilizar 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