Що таке еквівалент набору JavaScriptInterval / setTimeout в Android / Java?


129

Хтось може мені сказати, чи існує еквівалент setInterval / setTimeout для Android? Хтось має приклад, як це зробити?

Відповіді:


245

Як завжди з Android, існує багато способів зробити це, але якщо припустити, що ви просто хочете трохи пізніше запустити фрагмент коду на тій же нитці, я використовую це:

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

.. це майже рівнозначно

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

Це дуже вдале рішення для вибору ящиків та фрагмента
трансакції

6
Як я можу його скасувати, якщо потрібно?
Квентін Рой

Як ви отримуєте сферу діяльності в методі run ()?
Енді

@Анді так:MyActivityName.this.myFunctionOnActivity()
Бен Клейтон

1
@QuentinRoy: Handler timeout = new Handler(); final Runnable r = new Runnable{...}; timeout.postDelayed(r, 300);і якщо ви хочете скасувати це:timeout.removeCallbacks(r);
Bastian Springer

101

setInterval ()

функція, яка повторюється кожні n мілісекунд

Javascript

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

Орієнтовна java еквівалентна

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

setTimeout ()

функція, яка працює лише через п мілісекунд

Javascript

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

Орієнтовна java еквівалентна

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

5
Щодо scheduleAtFixedRateметоду, як ви скасуєте таймер у межах діяльності, коли ця діяльність закінчиться?
Аврораніл

2
@ user824294 ви можете зберегти свій примірник Timer у змінній та викликати "cancel ()", коли ви хочете зупинити заплановані завдання - Timer t = new Timer (); t.scheduleAtFixedRate (...); - А потім зателефонуйте t.cancel (); коли завгодно.
Aebsubis

14

Якщо ви не переживаєте прокидання телефону або повернення програми з мертвих, спробуйте:

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

На моєму телефоні (Huawei P Smart) Обробник не будить пристрій зі сну ( як це зауважив apanloco в іншій відповіді )
Franco

13

Залежно від того, чого ви насправді хочете досягти, варто поглянути на Android Handlers:

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

Якщо ви раніше використовували javascript setTimeout () тощо для планування виконання завдання в майбутньому, це спосіб Android робити це (postDelayed / sendMessageDelayed).

Зауважте, що ні обробники, ні таймери не змушують телефон Android прокидатися зі сну. Іншими словами, якщо ви хочете запланувати щось насправді, навіть якщо екран вимкнено / процесор спить, вам також потрібно перевірити AlarmManager.


5

Я не знаю багато про JavaScript, але я думаю, що Таймери можуть бути тим, що ви шукаєте.

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

За посиланням:

Один знімок планується виконати в абсолютний час або після відносної затримки. Повторювані завдання плануються з фіксованим періодом або з фіксованою ставкою.


Примітка. Він викликає вас на фоновому потоці, а не на головному / потоці інтерфейсу користувача.
Панг

Це не відповідь, а посилання на зовнішню інформацію, яка може містити або не містити рішення ОП. Будь ласка, вставте відповідний код, який OP може використовувати!
Лев

5

Перша відповідь, безумовно, правильна відповідь, і це те, на чому я базував цю лямбда-версію, яка синтаксисом набагато коротша. Оскільки у Runnable є лише 1 метод заміщення "run ()", ми можемо використовувати лямбда:

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

Ось еквівалент setTimeout, який в основному корисний при спробі оновлення інтерфейсу користувача після затримки.

Як ви можете знати, оновити інтерфейс користувача можна лише за допомогою потоку інтерфейсу користувача. AsyncTask робить це для вас, викликаючи його метод onPostExecute з цього потоку.

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. Аналогічно onProgressUpdate()також можна використовувати для моделювання setInterval(). 2. AsyncTask працює на пулі потоків (або просто на одну нитку), так що. можливо, доведеться почекати, поки не AsyncTaskзакінчиться інше ; б . це займе одну нитку з пулу.
Панг

Існує багато проблем із використанням завдання async у цьому контексті (лише одна нитка та блокування потоку без причини) - інші рішення набагато кращі.
Елементальний

4

Я створював mp3-плеєр для Android, я хотів оновлювати поточний час кожні 500 мс, щоб я це зробив так

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

який викликає той же метод рекурсивно

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.