Android: ejecuta un método periódicamente usando la llamada postDelayed ()

Tengo una situación en una aplicación de Android en la que quiero iniciar una actividad de red (envío de algunos datos) que debe ejecutarse cada segundo. Lo logro de la siguiente manera:

En el onCreate() tengo el código:

 tv = new TextView(this); tv.postDelayed(sendData, 1000); 

La función sendData() :

  Handler handler = new Handler(); private Runnable sendData=new Runnable(){ public void run(){ try { //prepare and send the data here.. handler.removeCallbacks(sendData); handler.postDelayed(sendData, 1000); } catch (Exception e) { e.printStackTrace(); } } }; 

El problema viene así: cuando el usuario presiona los botones de retroceso y la aplicación sale (la IU desaparece) la función sendData() aún se ejecuta, que es lo que quiero. Ahora cuando el usuario reinicia la aplicación, mi onCreate() vuelve a llamar y obtengo sendData() invocado dos veces por segundo. Sigue así. Cada vez que el usuario sale y comienza de nuevo, se sendData() un sendData() por segundo.

¿Qué estoy haciendo mal? ¿Es mi new Handler() creando un problema? ¿Cuál es la mejor manera de manejar esto? Deseo una llamada a sendData() por segundo hasta que el usuario salga de la aplicación (administrador de la aplicación de formulario).

¿Por qué no crea servicio y pone lógica en onCreate() ? En este caso, incluso si presiona el botón Atrás, el servicio seguirá ejecutándose. y una vez que ingrese a la aplicación, no volverá a llamar a onCreate() . Más bien llamará a onStart()

 final Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { //Do something after 100ms Toast.makeText(c, "check", Toast.LENGTH_SHORT).show(); handler.postDelayed(this, 2000); } }, 1500); 

Tal vez involucre los métodos del ciclo de vida de la actividad para lograr esto:

 Handler handler = new Handler(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); handler.post(sendData); } @Override protected void onDestroy() { super.onDestroy(); handler.removeCallbacks(sendData); } private final Runnable sendData = new Runnable(){ public void run(){ try { //prepare and send the data here.. handler.postDelayed(this, 1000); } catch (Exception e) { e.printStackTrace(); } } }; 

En este enfoque, si presiona la tecla de retroceso en su actividad o llame a finish(); , también detendrá los llamamientos postDelayed .

Puedes simplificar el código de esta manera.

Solo escribe:

 final Handler handler = new Handler(); handler.postDelayed (() -> { //your code here }, TIME_DELAY); 

Por favor, compruebe que funciona debajo de mi código de abajo que su controlador se ejecutará después de cada 1 segundo cuando esté en la misma actividad

  HandlerThread handlerThread = new HandlerThread("HandlerThread"); handlerThread.start(); handler = new Handler(handlerThread.getLooper()); runnable = new Runnable() { @Override public void run() { handler.postDelayed(this, 1000); } }; handler.postDelayed(runnable, 1000); 
 Handler h = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); if (msg.what==0){ // do stuff h.removeMessages(0); // clear the handler for those messages with what = 0 h.sendEmptyMessageDelayed(0, 2000); } } }; h.sendEmptyMessage(0); 

Creo que puedes experimentar con diferentes indicadores de actividad, ya que suena como varias instancias.

“singleTop” “singleTask” “singleInstance”

Son los que probaría, se pueden definir dentro del manifiesto.

http://developer.android.com/guide/topics/manifest/activity-element.html

Debe establecer andrid: allowRetainTaskState = “true” para iniciar la actividad en Manifest.xml. Si esta actividad no es actividad de lanzamiento. deberías configurar android: launchMode = “singleTask” en esta actividad