2012-07-11 20 views
70

Estoy desarrollando una aplicación Android 2.3.3 y necesito ejecutar un método cada X segundos.Cómo ejecutar un método cada X segundos

En iOS, tengo NSTimer, pero en Android no sé qué usar.

Alguien me ha recomendado Handler; otra me recomienda AlarmManager pero no sé qué método se ajusta mejor con NSTimer.

Este es el código que desea implementar en Android:

timer2 = [ 
    NSTimer scheduledTimerWithTimeInterval:(1.0f/20.0f) 
    target:self 
    selector:@selector(loopTask) 
    userInfo:nil 
    repeats:YES 
]; 

timer1 = [ 
    NSTimer scheduledTimerWithTimeInterval:(1.0f/4.0f) 
    target:self 
    selector:@selector(isFree) 
    userInfo:nil 
    repeats:YES 
]; 

necesito algo lo que funciona como NSTimer.

¿Qué me recomiendas?

+1

Define "el mejor". ¿De qué manera quieres que sea lo mejor? –

+0

No sé qué método se ajusta mejor con NSTimer. – VansFannel

+0

@VansFannel ¿Cuánto tiempo quieres? – FoamyGuy

Respuesta

110

Esto realmente depende de cuánto tiempo aparte que necesita para ejecutar la función.

Si es => 10 minutos → Me gustaría ir con Alarm Manager.

// Some time when you want to run 
Date when = new Date(System.currentTimeMillis());  

try{ 
    Intent someIntent = new Intent(someContext,MyReceiver.class); // intent to be launched 

    // note this could be getActivity if you want to launch an activity 
    PendingIntent pendingIntent = PendingIntent.getBroadcast(
     context, 
     0, // id, optional 
     someIntent, // intent to launch 
     PendingIntent.FLAG_CANCEL_CURRENT); // PendintIntent flag 

    AlarmManager alarms = (AlarmManager) context.getSystemService(
     Context.ALARM_SERVICE); 

    alarms.setRepeating(AlarmManager.RTC_WAKEUP, 
     when.getTime(), 
     AlarmManager.INTERVAL_FIFTEEN_MINUTES, 
     pendingIntent); 

}catch(Exception e){ 
    e.printStackTrace(); 
} 

Y luego recibe estas transmisiones a través del receptor de difusión. Tenga en cuenta que será necesario registrar el éter en el manifiesto de su aplicación o mediante el método context.registerReceiver(receiver,filter);. Para obtener más información sobre los receptores de difusión, consulte los documentos oficiales. Broadcast Receiver.

public class MyReceiver extends BroadcastReceiver{ 

    @Override 
    public void onReceive(Context context, Intent intent) 
    { 
     //do stuffs 
    } 
} 

Si es = < 10 minutos → Me gustaría ir con un Handler.

Handler handler = new Handler(); 
int delay = 1000; //milliseconds 

handler.postDelayed(new Runnable(){ 
    public void run(){ 
     //do something 
     handler.postDelayed(this, delay); 
    } 
}, delay); 
+0

¿Por qué diferentes sugerencias dependiendo del tiempo de retraso? –

+3

Eficiencia, en los documentos de AlarmManager indica que no se debe usar para ninguna tarea repetitiva de intervalos pequeños. – Jug6ernaut

+5

@ SimonAndréForsberg en [los documentos de AlarmManager] (http://developer.android.com/reference/android/app/AlarmManager.html) indica que Handler es el método preferido y más eficiente para usar en tics cortos: "Nota: Alarm Manager está diseñado para casos en los que desee que su código de aplicación se ejecute en un momento específico, incluso si su aplicación no se está ejecutando actualmente. Para las operaciones de temporización normales (ticks, timeouts, etc.) es más fácil y mucho más eficiente de usar Entrenador de animales." – FoamyGuy

68

Uso del temporizador para cada segundo ...

new Timer().scheduleAtFixedRate(new TimerTask() { 
       @Override 
       public void run() {} 
      }, 0, 1000);//put here time 1000 milliseconds=1 second 
+0

He actualizado la pregunta con detalles sobre lo que intento hacer. – VansFannel

+0

No utilice el temporizador (http://www.mopri.de/2010/timertask-bad-do-it-the-android-way-use-a-handler/), use Handler o ScheduledThreadPoolExecutor. – AppiDevo

18

prueba este código para llamar manejador cada 15 segundos y detenerlo cuando la actividad no visible

Handler h = new Handler(); 
    int delay = 15*1000; //1 second=1000 milisecond, 15*1000=15seconds 
    Runnable runnable; 

    @Override 
    protected void onResume() { 
     //start handler as activity become visible 

     h.postDelayed(new Runnable() { 
      public void run() { 
       //do something 

       runnable=this; 

       h.postDelayed(runnable, delay); 
      } 
     }, delay); 

     super.onResume(); 
    } 

    @Override 
    protected void onPause() { 
     h.removeCallbacks(runnable); //stop handler when activity not visible 
     super.onPause(); 
    } 
+3

Esto es lo que estaba buscando. Perfecto. – viper

6

Si está familiarizado con RxJava, puede utilizar Observable.interval(), que es bastante limpio .

Observable.interval(60, TimeUnits.SECONDS) 
      .flatMap(new Function<Long, ObservableSource<String>>() { 
       @Override 
       public ObservableSource<String> apply(@NonNull Long aLong) throws Exception { 
        return getDataObservable(); //Where you pull your data 
       } 
      }); 

El inconveniente de esto es que tiene que arquitecto sondear sus datos de una manera diferente. Sin embargo, hay muchos beneficios para la forma de Programación Reactiva:

  1. En lugar de controlar sus datos mediante una devolución de llamada, crea una secuencia de datos a los que se suscribe. Esto separa la preocupación de la lógica de "datos de sondeo" y la lógica de "llenar UI con sus datos" para que no mezcle su código de "fuente de datos" y su código de UI.
  2. Con RxAndroid, puede manejar hilos en solo 2 líneas de código.

    Observable.interval(60, TimeUnits.SECONDS) 
         .flatMap(...) // polling data code 
         .subscribeOn(Schedulers.newThread()) // poll data on a background thread 
         .observeOn(AndroidSchedulers.mainThread()) // populate UI on main thread 
         .subscribe(...); // your UI code 
    

Por favor, echa un vistazo a RxJava. Tiene una gran curva de aprendizaje, pero hará que manejar llamadas asíncronas en Android sea mucho más fácil y más limpio.

0

Aquí he utilizado un hilo en onCreate() una actividad repeatly, temporizador no permite que todo lo que en algunos casos la rosca es la solución

 Thread t = new Thread() { 
     @Override 
     public void run() { 
      while (!isInterrupted()) { 
       try { 
        Thread.sleep(10000); //1000ms = 1 sec 
        runOnUiThread(new Runnable() { 
         @Override 
         public void run() { 

          SharedPreferences mPrefs = getSharedPreferences("sam", MODE_PRIVATE); 
          Gson gson = new Gson(); 
          String json = mPrefs.getString("chat_list", ""); 
          GelenMesajlar model = gson.fromJson(json, GelenMesajlar.class); 
          String sam = ""; 

          ChatAdapter adapter = new ChatAdapter(Chat.this, model.getData()); 
          listview.setAdapter(adapter); 
          // listview.setStackFromBottom(true); 
          // Util.showMessage(Chat.this,"Merhabalar"); 
         } 
        }); 

       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
    }; 

    t.start(); 

En caso de que tuviera que puede ser excavado por las

@Override 
protected void onDestroy() { 
    super.onDestroy(); 
    Thread.interrupted(); 
    //t.interrupted(); 
} 
+0

por favor describa la situación cuando mi respuesta no funcionará –

+0

Hola Umar. Necesitaba un círculo todo el tiempo en que la aplicación está viva. Handler hizo que la repetición se mantuviera viva mientras la actividad estaba activa, pero necesito el círculo mientras pude visitar otras actividades también. Así que el hilo es la solución de esta manera, seguro que también tiene su problema. – Sam

Cuestiones relacionadas