2012-07-11 16 views
70

Pracuję nad aplikacją Android 2.3.3 i muszę uruchomić metodę co X sekund.Jak uruchomić metodę co X sekund

W systemie iOS mam NSTimer, ale w systemie Android nie wiem, czego używać.

Ktoś polecił mi Handler; jeszcze jeden polecam AlarmManager, ale nie wiem, która metoda pasuje lepiej z NSTimer.

Jest to kod Chcę zaimplementować w Androidzie:

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 
]; 

muszę coś, co działa jak NSTimer.

Co polecasz mi?

+1

Zdefiniuj "najlepszy". W jaki sposób chcesz być najlepszy? –

+0

Nie wiem, która metoda lepiej pasuje do NSTimer. – VansFannel

+0

@VansFannel Jak długo potrzebujesz przerwy? – FoamyGuy

Odpowiedz

110

To naprawdę zależy od tego jak długo poza trzeba uruchomić funkcję.

Jeśli jest to>> 10 minut → Przejdę z Menedżerem alarmów.

// 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(); 
} 

A potem otrzymasz te transmisje za pośrednictwem odbiornika telewizyjnego. Zwróć uwagę, że będzie to konieczne do zarejestrowania eteru w manifeście aplikacji lub za pomocą metody context.registerReceiver(receiver,filter);. Aby uzyskać więcej informacji na temat odbiorników transmisji, zapoznaj się z oficjalnymi dokumentami. Broadcast Receiver.

public class MyReceiver extends BroadcastReceiver{ 

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

Jeśli to = < 10 minut → pójdę z Handler.

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

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

Dlaczego różne sugestie zależą od opóźnienia? –

+3

Wydajność, w dokumentach programu AlarmManager stwierdza, że ​​nie należy jej używać do wykonywania powtarzających się małych zadań. – Jug6ernaut

+5

@ SimonAndréForsberg w dokumencie [AlarmManager docs] (http://developer.android.com/reference/android/app/AlarmManager.html) stwierdza, że ​​Handler jest preferowaną i bardziej skuteczną metodą do zastosowania w przypadku krótkich kleszczy: "Uwaga: Menedżer alarmów jest przeznaczony do przypadków, w których chcesz uruchomić kod aplikacji w określonym czasie, nawet jeśli aplikacja nie jest aktualnie uruchomiona. W przypadku zwykłych operacji czasowych (tykanie, przekroczenia czasu itp.) Jest łatwiej i wydajniej używać Treser." – FoamyGuy

68

Wykorzystanie timera dla każdej sekundzie ...

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

Zaktualizowałem pytanie, podając szczegółowe informacje o tym, co próbuję zrobić. – VansFannel

+0

Nie używaj Timera (http://www.mopri.de/2010/timertask-bad-do-it-the-android-way-use-a-handler/), użyj Handler lub ScheduledThreadPoolExecutor. – AppiDevo

18

wypróbować ten kod do procedury obsługi zadzwonić co 15 sekund i zatrzymać go, gdy działalność nie jest widoczna

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

Tego właśnie szukałem. Idealny. – viper

6

Jeśli jesteś zaznajomiony z RxJava, można użyć Observable.interval(), która jest dość schludny .

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 
       } 
      }); 

Wadą tego jest to, że musisz architekt ankietować swoje dane w inny sposób. Istnieje jednak wiele korzyści dla Reactive Programming:

  1. Zamiast kontrolować dane za pomocą wywołania zwrotnego, tworzysz strumień danych, które subskrybujesz. Oddziela to problem logiki "danych pollingowych" od logiki "zapełniając interfejs użytkownika danymi", aby nie mieszać kodu "źródła danych" z kodem użytkownika.
  2. Dzięki RxAndroid możesz obsługiwać wątki tylko w 2 liniach kodu.

    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 
    

Proszę sprawdzić RxJava. Ma wysoką krzywą uczenia się, ale sprawi, że obsługa połączeń asynchronicznych w systemie Android będzie znacznie łatwiejsza i czystsza.

0

Tutaj użyłem wątek w onCreate() działalność repeatly, timer nie zezwala wszystko w niektórych przypadkach Temat jest rozwiązaniem

 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(); 

w razie potrzeby można je zatykać przez

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

proszę opisać sytuację, w której moja odpowiedź nie zadziała –

+0

Witaj Umar. Przez cały czas potrzebowałem okręgu, w którym aplikacja jest żywa, Handler uczynił powtórzenie żywym, podczas gdy aktywność jest żywa, ale potrzebuję okręgu, podczas gdy byłem w stanie odwiedzać inne działania. Nić jest więc rozwiązaniem w ten sposób, że ma również swoją walkę. – Sam

Powiązane problemy