thread studio example delaymillis android multithreading timer handler postdelayed

android - studio - Actualización de la interfaz de usuario con Runnable y PostDelayed no funciona con la aplicación de temporizador



httphandler android (6)

  1. Necesitas hacer actualizaciones de la interfaz de usuario en el hilo de la interfaz de usuario.
  2. Debe crear un controlador en el subproceso de la interfaz de usuario para ejecutar tareas en el subproceso de la interfaz de usuario.

    public class MainActivity extends AppCompatActivity private Handler mHandler; @Override protected void onCreate(Bundle savedInstanceState) { mHandler = new Handler(); // This to create the Handler in the UI thread // ... }

He examinado todas las discusiones y temas que puedo encontrar para que esto funcione, pero no lo es. Tengo un temporizador simple que actualiza una vista de texto (mTimeTextField en el siguiente ejemplo). El método de ejecución mUpdateTimeTask se está ejecutando correctamente (cada segundo) pero el campo UI / texto no se está actualizando.

Tengo un código basado en la información encontrada aquí:

http://android-developers.blogspot.com/2007/11/stitch-in-time.html http://developer.android.com/resources/articles/timed-ui-updates.html

Aquí está el código:

package com.something.handlertest; import com.something.handlertest.R; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.os.SystemClock; import android.view.View; import android.widget.Button; import android.widget.TextView; public class Test extends Activity { private Handler mHandler = new Handler(); private int labelNo = 0; private long currTime = 0L; private long mStartTime = 0L; TextView mTimeTextField; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mTimeTextField = (TextView)findViewById(R.id.timeTextFieldl); Button startButton = (Button)findViewById(R.id.start_button); startButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { if (mStartTime == 0L) { mStartTime = System.currentTimeMillis(); mHandler.removeCallbacks(mUpdateTimeTask); mHandler.postDelayed(mUpdateTimeTask, 100); } } }); } private Runnable mUpdateTimeTask = new Runnable() { public void run() { final long start = mStartTime; //long millis = SystemClock.uptimeMillis() - start; long millis = SystemClock.uptimeMillis(); int seconds = (int) (millis / 1000); int minutes = seconds / 60; seconds = seconds % 60; //setContentView(mTimeTextField); This will blow up if I use it if (seconds < 10) { mTimeTextField.setText("" + minutes + ":0" + seconds); } else { mTimeTextField.setText("" + minutes + ":" + seconds); } //mHandler.postAtTime(this, // start + (((minutes * 60) + seconds + 1) * 1000)); mHandler.postAtTime(this, 1000); } }; }

Por algunas sugerencias, he intentado agregar:

setContentView(mTimeLabel);

Pero esto se quejará de quejarse de que la vista no tiene un padre. Para tu información, tengo un

setContentView(R.layout.main);

llamar en mi onCreate() .


Asegúrese de que R.id.timeTextFieldl sea un ID correcto.


Esto podría estar más en la línea de lo que está buscando:

private Runnable mUpdateTimeTask = new Runnable() { public void run() { final long start = mStartTime; long elapseTime = System.currentTimeMillis() - start; int seconds = (int) (elapseTime / 1000); int minutes = seconds / 60; seconds = seconds % 60; if (seconds < 10) { mTimeTextField.setText("" + minutes + ":0" + seconds); } else { mTimeTextField.setText("" + minutes + ":" + seconds); } // add a delay to adjust for computation time long delay = (1000 - (elapseTime%1000)); mHandler.postDelayed(this, delay); } };

Encontré que esta es una buena manera de agregar un tiempo a los videos


La vista solo se puede mostrar en el hilo de la interfaz de usuario. tienes que iniciar el runnable usando ru


Reemplazar

mHandler.postAtTime(this, 1000);

con

mHandler.postDelayed(this, 1000);


if (seconds < 10) { mTimeTextField.setText("" + minutes + ":0" + seconds); } else { mTimeTextField.setText("" + minutes + ":" + seconds); }

más corto es:

mTimeTextField.setText(minutes + ":" + (seconds < 10 ? "0" : "") + seconds);

pero mejor manera es usar String.format ^

mTimeTextField.setText(String.format("%d:%s%d", minutes, (seconds < 10 ? "0" : ""), seconds);