2012-07-24 9 views
11

Prima di tutto, non potevo nemmeno scegliere il metodo da utilizzare, sto leggendo per ore e qualcuno dice di usare "Gestori", qualcuno dice di usare "Timer". Ecco cosa cerco di ottenere:Android - Esegui un thread ripetutamente entro un timer

A preferenza, esiste un'impostazione (casella di controllo) che abilita/disabilita il lavoro ripetuto. Mentre quella casella è selezionata, il timer dovrebbe iniziare a funzionare e il thread dovrebbe essere eseguito ogni x secondi. Non appena la casella di controllo è deselezionata, il timer dovrebbe fermarsi.

Ecco il mio codice:

Verificare se se casella è selezionata o meno, se selezionato vuoto 'refreshAllServers' sarà eseguito, che fa il lavoro con timer.

boolean CheckboxPreference = prefs.getBoolean("checkboxPref", true); 
       if(CheckboxPreference == true) { 
        Main main = new Main(); 
        main.refreshAllServers("start"); 
       } else { 
        Main main = new Main(); 
        main.refreshAllServers("stop"); 
       } 

Il vuoto refreshAllServers che fa il processo timer:

public void refreshAllServers(String start) { 

    if(start == "start") { 

     // Start the timer which will repeatingly execute the thread 

    } else { 

     // stop the timer 

      } 

Ed ecco come eseguo il mio thread: (funziona bene senza timer)

Thread myThread = new MyThread(-5); 
       myThread.start(); 

Quello che ho cercato?

Ho provato qualsiasi esempio che potrei vedere da Google (gestori, timer) nessuno di loro ha funzionato, sono riuscito a avviare il timer una volta, ma l'interruzione non ha funzionato. Il più semplice & codice comprensibile che ho visto nella mia ricerca era questo:

new java.util.Timer().schedule( 
     new java.util.TimerTask() { 
      @Override 
      public void run() { 
       // your code here 
      } 
     }, 
     5000 
); 
+1

vedere se la risposta [qui] (http://stackoverflow.com/questions/8098806/where-do-i-create-and-use-scheduledthreadpoolexecutor-timertask-or-handler/8102488#8102488) aiuta. – yorkw

risposta

34

Basta semplicemente utilizzare sotto snippet

private Handler handler = new Handler(); 
private Runnable runnable = new Runnable() { 
    public void run() { 
     // 
     // Do the stuff 
     // 

     handler.postDelayed(this, 1000); 
    } 
}; 
runnable.run(); 

per fermarlo utilizzare

handler.removeCallbacks(runnable); 

dovrebbe fare il trucco.

+0

La tua soluzione ha funzionato bene, come ho trovato qualche altra soluzione. – sarkolata

+0

Penso che questa sia la soluzione migliore. –

+2

cosa succede se l'utente vuole realizzare qualcosa che usi la connessione ad internet? l'applicazione di quanto sopra renderà il gestore e l'esecuzione eseguibile sul thread dell'interfaccia utente, che impedisce di fare qualsiasi cosa di rete. È necessario implementare il thread lì. – tony9099

1

penserei usare AlarmManager http://developer.android.com/reference/android/app/AlarmManager.html

Se casella di controllo è su chiamata del metodo in cui

AlarmManager alarmManager = (AlarmManager)SecureDocApplication.getContext() 
    .getSystemService(Context.ALARM_SERVICE); 
PendingIntent myService = PendingIntent.getService(context, 0, 
       new Intent(context, MyService.class), 0); 

long triggerAtTime = 1000; 
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, triggerAtTime, 5000 /* 5 sec*/, 
       myService); 

Se casella di controllo è spento cancel alarm manager

alarmManager.cancel(myService); 
+0

E qual è la parte che inserirò il mio codice? – sarkolata

+1

Avere una variabile membro della classe che è l'istanza di gestione allarmi. Quando la casella è attiva, chiama un metodo con quel codice. quando il metodo di chiamata off per spegnere gestore di allarmi. Succederà quando l'utente naviga attraverso le attività, quindi nella classe Application ereditata. Se l'utente può uscire dall'app e deve ancora essere in esecuzione, allora nel servizio. – Maxim

1

Utilizzare un CountDownTimer. Il modo in cui funziona è che chiamerà un metodo su ogni tick del timer e un altro metodo quando il timer termina. A quel punto è possibile riavviare se necessario. Inoltre penso che dovresti probabilmente avviare AsyncTask piuttosto che i thread. Si prega di non provare a gestire i propri thread in Android. Prova come sotto Funziona come un orologio.

CountDownTimer myCountdownTimer = new CountDownTimer(30000, 1000) { 

public void onTick(long millisUntilFinished) { 
    mTextField.setText("seconds remaining: " + millisUntilFinished/1000); 
    // Kick off your AsyncTask here. 
} 

public void onFinish() { 
    mTextField.setText("done!"); 
    // the 30 seconds is up now so do make any checks you need here. 
} 
}.start(); 
+0

Questo non fa ripetutamente la cosa. Lo ha fatto una volta poi fermato! – sarkolata

+0

Sì, non viene eseguito a tempo indeterminato. Se vuoi eseguirlo a tempo indeterminato puoi prendere in considerazione un servizio in background. D'altro canto, non vi è nulla che impedisca di riavviare il timer del conto alla rovescia se le condizioni sono corrette o se si imposta una durata più lunga. –

2

Grazie a tutti, ho risolto il problema con l'utilizzo di Timer.

   timer = new Timer(); 
      timer.scheduleAtFixedRate( 
         new java.util.TimerTask() { 
          @Override 
          public void run() { 
           for(int i = 0; i < server_amount; i++) { 
             servers[i] = "Updating...";          handler.sendEmptyMessage(0); 
             new MyThread(i); 
             myThread.start(); 
         } 


        }}, 
        2000, 5000 
        ); 
+0

Si prega di indicare i vantaggi di questa soluzione rispetto agli altri. Non lo vedo –

+0

Nessun vantaggio, ho appena scoperto che la risposta di Coders Paradise funziona anche dopo che il mio ha funzionato. – sarkolata

0

"[ScheduledThreadPoolExecutor] classe è preferibile Timer quando sono necessarie più thread di lavoro, o quando è richiesta la flessibilità supplementare o capacità di ThreadPoolExecutor (che questa classe estende)."

per ...

https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html

Non è molto di più del gestore, ma ha la possibilità di eseguire esattamente ogni tanto (vizio un ritardo dopo ogni completamento di calcolo).

import java.util.concurrent.ScheduledThreadPoolExecutor; 
import java.util.concurrent.TimeUnit; 


... 


final int THREAD_POOL_SIZE = 10; 
final int START_DELAY = 0; 
final int TIME_PERIOD = 5; 
final TimeUnit TIME_UNIT = TimeUnit.SECONDS; 

ScheduledThreadPoolExecutor pool; 

Runnable myPeriodicThread = new Runnable() { 
    @Override 
    public void run() { 
     refreshAllServers(); 
    } 
}; 


public void startTimer(){ 

    pool.scheduleAtFixedRate(myPeriodicThread, 
      START_DELAY, 
      TIME_PERIOD, 
      TIME_UNIT); 

} 

public void stopTimer(){ 

    pool.shutdownNow(); 

}