Jaki jest odpowiednik kodu JavaScript setInterval / setTimeout w systemie Android / Java?


129

Czy ktoś może mi powiedzieć, czy istnieje odpowiednik setInterval / setTimeout dla Androida? Czy ktoś ma jakiś przykład, jak to zrobić?

Odpowiedzi:


245

Jak zawsze w przypadku Androida, można to zrobić na wiele sposobów, ale zakładając, że po prostu chcesz uruchomić fragment kodu nieco później w tym samym wątku, używam tego:

new android.os.Handler().postDelayed(
    new Runnable() {
        public void run() {
            Log.i("tag", "This'll run 300 milliseconds later");
        }
    }, 
300);

.. to jest prawie równoważne z

setTimeout( 
    function() {
        console.log("This will run 300 milliseconds later");
    },
300);

To bardzo dobre rozwiązanie do wyboru szuflady i fragmentTransaction
Gonçalo

6
Jak mogę to anulować, jeśli zajdzie taka potrzeba?
Quentin Roy,

Jak uzyskać zakres aktywności w metodzie run ()?
Andy

@Andy w ten sposób:MyActivityName.this.myFunctionOnActivity()
Ben Clayton,

1
@QuentinRoy: Handler timeout = new Handler(); final Runnable r = new Runnable{...}; timeout.postDelayed(r, 300);a jeśli chcesz to anulować:timeout.removeCallbacks(r);
Bastian Springer

101

setInterval ()

funkcja, która powtarza się co n milisekund

Javascript

 setInterval(function(){ Console.log("A Kiss every 5 seconds"); }, 5000);

Przybliżony odpowiednik Java

new Timer().scheduleAtFixedRate(new TimerTask(){
    @Override
    public void run(){
       Log.i("tag", "A Kiss every 5 seconds");
    }
},0,5000);

setTimeout ()

funkcja, która działa tylko po n milisekundach

Javascript

setTimeout(function(){ Console.log("A Kiss after 5 seconds"); },5000);

Przybliżony odpowiednik Java

new android.os.Handler().postDelayed(
    new Runnable() {
        public void run() {
            Log.i("tag","A Kiss after 5 seconds");
        }
}, 5000);

5
W przypadku tej scheduleAtFixedRatemetody, jak anulować licznik czasu w ramach czynności po zakończeniu tej czynności?
auroranil

2
@ user824294 możesz zapisać swoją instancję Timera w zmiennej i wywołać "cancel ()", gdy chcesz zatrzymać zaplanowane zadania - Timer t = new Timer (); t.scheduleAtFixedRate (...); - A następnie wywołaj t.cancel (); kiedy tylko chcesz.
Aebsubis

14

Jeśli nie martwisz się wybudzeniem telefonu lub przywróceniem aplikacji z martwych, spróbuj:

// Param is optional, to run task on UI thread.     
Handler handler = new Handler(Looper.getMainLooper());
Runnable runnable = new Runnable() {
    @Override
    public void run() {
        // Do the task...
        handler.postDelayed(this, milliseconds) // Optional, to repeat the task.
    }
};
handler.postDelayed(runnable, milliseconds);

// Stop a repeating task like this.
handler.removeCallbacks(runnable);

Na moim telefonie (Huawei P Smart) Handler nie wybudza urządzenia z trybu uśpienia ( jak zauważył apanloco w innej odpowiedzi )
Franco

13

W zależności od tego, co naprawdę chcesz osiągnąć, spójrz na moduły obsługi Androida:

http://developer.android.com/reference/android/os/Handler.html

Jeśli wcześniej używałeś javascript setTimeout () etc do planowania zadania do wykonania w przyszłości, jest to sposób na zrobienie tego w Androidzie (postDelayed / sendMessageDelayed).

Pamiętaj, że ani Handlery, ani Timery nie powodują wybudzenia telefonu z Androidem z trybu uśpienia. Innymi słowy, jeśli chcesz zaplanować, aby coś się wydarzyło, nawet jeśli ekran jest wyłączony / procesor śpi, musisz również sprawdzić AlarmManager.


5

Nie wiem zbyt wiele o JavaScript, ale myślę, że Timery mogą być tym, czego szukasz.

http://developer.android.com/reference/java/util/Timer.html

Z linku:

Zabiegi jednorazowe zaplanowano na czas bezwzględny lub po względnym opóźnieniu. Zadania cykliczne są planowane na stały okres lub według stałej stawki.


Uwaga: wywołuje Cię w wątku w tle, a nie w wątku głównym / UI.
Pang

To nie jest odpowiedź, ale odniesienie do informacji zewnętrznych, które mogą, ale nie muszą zawierać rozwiązania PO. Proszę wkleić odpowiedni kod, którego OP może użyć!
Lew

5

Pierwsza odpowiedź jest zdecydowanie poprawna i na niej oparłem tę wersję lambda, która jest znacznie krótsza w składni. Ponieważ Runnable ma tylko jedną metodę nadpisywania „run ()”, możemy użyć lambda:

this.m_someBoolFlag = false;
new android.os.Handler().postDelayed(() -> this.m_someBoolFlag = true, 300);

5
import java.util.Timer;
import java.util.TimerTask;

class Clock {
    private Timer mTimer = new Timer();

    private int mSecondsPassed = 0;
    private TimerTask mTask = new TimerTask() {
        @Override
        public void run() {
            mSecondsPassed++;
            System.out.println("Seconds passed: " + mSecondsPassed);
        }
    };

    private void start() {
        mTimer.scheduleAtFixedRate(mTask, 1000, 1000);
    }

    public static void main(String[] args) {
        Clock c = new Clock();
        c.start();
    }
}

4

Oto odpowiednik setTimeout, przydatny głównie podczas próby zaktualizowania interfejsu użytkownika po opóźnieniu.

Jak być może wiesz, aktualizację interfejsu użytkownika można przeprowadzić tylko z poziomu wątku interfejsu użytkownika. AsyncTask robi to za Ciebie, wywołując metodę onPostExecute z tego wątku.

new AsyncTask<Void, Void, Void>() {
        @Override
        protected Void doInBackground(Void... params) {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
            }

            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            // Update the User Interface
        }

    }.execute();

3
1. Podobnie onProgressUpdate()może być również używany do symulacji setInterval(). 2. AsyncTask działa na puli wątków (lub tylko pojedynczym wątku), więc plik. może trzeba będzie poczekać, aż AsyncTaskskończy się inny ; b . zajmie jeden wątek z puli.
Pang

W tym kontekście jest wiele problemów z korzystaniem z zadania asynchronicznego (tylko jeden wątek i blokowanie wątku bez powodu) - inne rozwiązania są znacznie lepsze.
Elemental

4

Tworzyłem odtwarzacz mp3 na Androida, chciałem aktualizować aktualny czas co 500 ms, więc zrobiłem to w ten sposób

setInterval

private void update() {
    new android.os.Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            long cur = player.getCurrentPosition();
            long dur = player.getDuration();
            currentTime = millisecondsToTime(cur);
            currentTimeView.setText(currentTime);
            if (cur < dur) {
                updatePlayer();
            }

            // update seekbar
            seekBar.setProgress( (int) Math.round((float)cur / (float)dur * 100f));
        }
    }, 500);
}

która rekurencyjnie wywołuje tę samą metodę

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.