2012-04-18 17 views
28

Necesito realizar algunos códigos en intervalos regulares (conectarme a un servidor y extraer datos de la base de datos MySQL cada minuto). Para este fin tengo una clase de sincronización:Android: ejecutar código en intervalos regulares

public class Sync { 

    static private Handler handler = new Handler(); 
    Runnable task; 

    public Sync(Runnable task, long time) { 
     this.task = task; 
     handler.removeCallbacks(task); 
     handler.postDelayed(task, time); 
    } 
} 

y en mi Actividad tengo:

public void onCreate(Bundle savedInstanceState) { 
    ... 
    Sync sync = new Sync(call,60*1000); 
    ... 
} 

final private Runnable call = new Runnable() { 
    public void run() { 
    //This is where my sync code will be, but for testing purposes I only have a Log statement 
    Log.v("test","this will run every minute"); 
    } 
}; 

He intentado esto con un período de tiempo más corto para la prueba, pero sólo se ejecuta una vez. Cuando registra el mensaje por primera vez, también es el último. ¿Alguien ve lo que estoy haciendo aquí? ¡Gracias!

+0

scheduleWithFixedDelay de ScheduledThreadPoolExecutor es una opción más. –

Respuesta

48

Puede hacerlo utilizando el siguiente código, Espero que ayude!

final Handler handler = new Handler(); 
Runnable runnable = new Runnable() { 

    @Override 
    public void run() { 
     try{ 
      //do your code here 
     } 
     catch (Exception e) { 
      // TODO: handle exception 
     } 
     finally{ 
      //also call the same runnable to call it at regular interval 
      handler.postDelayed(this, 1000); 
     } 
    } 
}; 
+2

Sí, esto es lo que iba a decir. AlarmManager es más pesado y requiere manejo de Intentos para activar su Runnable. Tener tu Runnable volver a publicar al final si el camino a seguir. Y debe envolver su código en el Runnable con una prueba; finalmente, vuelva a publicar Runnable en la sección finally, para asegurarse de que nunca se omita. – Greg

+1

¡Esto lo resolvió, gracias! :) –

+27

Creo que el 'handler.postDelayed (this, 1000);' debe estar solo en la sección finally (no al final del bloque try); de lo contrario, se publicará dos veces. – Parmaia

2

handler.postDelayed(task, time); sólo ejecutará una vez, si desea que el código para activar a intervalos regulares que sugeriría un Timer y una TimerTask en lugar de un Handler y una Runnable.

TimerTasks se puede configurar para que se ejecute una vez, cada x segundos o con un período de tiempo fijo, p. x segundos: sin importar cuánto tiempo tardó en ejecutarse la última vez.

8

Primero tiene que declarar el controlador globalmente En segundo lugar, tiene que usar el método de publicación posterior de nuevo en el ejecutable para volver a activarlo.

@Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     Sync sync = new Sync(call,60*1000); 

    } 
    final private Runnable call = new Runnable() { 
     public void run() { 
     //This is where my sync code will be, but for testing purposes I only have a Log statement 
     Log.v("test","this will run every minute"); 
     handler.postDelayed(call,60*1000); 
     } 
    }; 
    public final Handler handler = new Handler(); 
    public class Sync { 


     Runnable task; 

     public Sync(Runnable task, long time) { 
      this.task = task; 
      handler.removeCallbacks(task); 
      handler.postDelayed(task, time); 
     } 
    } 


} 
1
 private void doSomethingRepeatedly() { 
     timer.scheduleAtFixedRate(new TimerTask() { 
      public void run() { 

        try{ 

        //Your code 

        } 
        catch (Exception e) { 
         // TODO: handle exception 
        } 

      } 
      }, 0, 10000); 
        } 
0

Una forma alternativa, el uso de ScheduledExecutorService scheduleAtFixedRate:

private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); 

public void beepEvery10Seconds() { 
    final Runnable beeper = new Runnable() { 
     public void run() { System.out.println("beep"); } 
    }; 
    final ScheduledFuture<?> beeperHandle = scheduler.scheduleAtFixedRate(beeper, 0, 10, SECONDS); 
} 
Cuestiones relacionadas