Tương đương với một setInterval / setTimeout của JavaScript trong Android / Java là gì?


129

Bất cứ ai cũng có thể cho tôi biết nếu một tương đương cho setInterval / setTimeout tồn tại cho Android không? Có ai có bất kỳ ví dụ về làm thế nào để làm điều đó?

Câu trả lời:


245

Như mọi khi với Android, có rất nhiều cách để làm điều này, nhưng giả sử bạn chỉ muốn chạy một đoạn mã sau đó trên cùng một chuỗi, tôi sử dụng cách này:

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

.. điều này là khá nhiều tương đương với

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

Đây là một giải pháp rất tốt để lựa chọn ngăn kéo và phân đoạn
Gonçalo

6
Làm thế nào tôi có thể hủy bỏ nó nếu tôi cần?
Quentin Roy

Làm thế nào để bạn có được phạm vi hoạt động trong phương thức run ()?
Andy

@Andy như thế này:MyActivityName.this.myFunctionOnActivity()
Ben Clayton

1
@QuentinRoy: Handler timeout = new Handler(); final Runnable r = new Runnable{...}; timeout.postDelayed(r, 300);và nếu bạn muốn hủy nó:timeout.removeCallbacks(r);
Bastian Springer

101

setInterval ()

chức năng lặp lại chính nó trong mỗi n mili giây

Javascript

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

Xấp xỉ java tương đương

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

setTimeout ()

chức năng chỉ hoạt động sau n mili giây

Javascript

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

Xấp xỉ java tương đương

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

5
Đối với scheduleAtFixedRatephương thức, làm thế nào để bạn hủy bộ hẹn giờ trong hoạt động sau khi hoạt động đó kết thúc?
auroranil

2
@ user824294 bạn có thể lưu phiên bản Timer của mình trong một biến và gọi "hủy ()" khi bạn muốn dừng các tác vụ theo lịch trình - Timer t = new Timer (); t.scheduleAtFixedRate (...); - Và sau đó gọi t.celon (); bất cứ khi nào bạn muốn.
Aebsubis

14

Nếu bạn không lo lắng về việc đánh thức điện thoại hoặc đưa ứng dụng của bạn trở về từ cõi chết, hãy thử:

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

Trên điện thoại của tôi (Huawei P Smart), Handler không đánh thức thiết bị từ chế độ ngủ ( như được nhận xét bởi apanloco trong một câu trả lời khác )
Franco

13

Tùy thuộc vào những gì bạn thực sự muốn đạt được, bạn nên xem qua Trình xử lý Android:

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

Nếu trước đây bạn đã sử dụng javascript setTimeout (), v.v. để lên lịch cho một tác vụ sẽ chạy trong tương lai, thì đây là cách thực hiện của Android (postDelayed / sendMessageDelayed).

Lưu ý rằng cả Handlers hay Timers đều không làm cho điện thoại Android thức dậy từ chế độ ngủ. Nói cách khác, nếu bạn muốn lên lịch để một cái gì đó thực sự xảy ra mặc dù màn hình tắt / cpu đang ngủ, bạn cũng cần kiểm tra Trình quản lý báo thức.


5

Tôi không biết nhiều về JavaScript, nhưng tôi nghĩ Timers có thể là thứ bạn đang tìm kiếm.

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

Từ liên kết:

One-shot được lên lịch để chạy ở một thời điểm tuyệt đối hoặc sau một độ trễ tương đối. Nhiệm vụ định kỳ được lên lịch với một khoảng thời gian cố định hoặc tỷ lệ cố định.


Lưu ý: Nó gọi bạn trên một luồng nền, không phải trên luồng chính / UI.
Pang

Đây không phải là một câu trả lời, mà là một tham chiếu đến thông tin bên ngoài thậm chí có thể có hoặc không chứa giải pháp OP. Vui lòng dán mã OP có liên quan có thể sử dụng!
Lev

5

Câu trả lời đầu tiên chắc chắn là câu trả lời đúng và là những gì tôi dựa trên phiên bản lambda này, nó ngắn hơn nhiều về cú pháp. Vì Runnable chỉ có 1 phương thức ghi đè "run ()", nên chúng tôi có thể sử dụng 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

Đây là một setTimeout tương đương, chủ yếu hữu ích khi cố gắng cập nhật Giao diện người dùng sau khi trì hoãn.

Như bạn có thể biết, việc cập nhật giao diện người dùng chỉ có thể được thực hiện từ luồng UI. AsyncTask thực hiện điều đó cho bạn bằng cách gọi phương thức onPostExecute của nó từ luồng đó.

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. Tương tự, onProgressUpdate()cũng có thể được sử dụng để mô phỏng setInterval(). 2. AsyncTask chạy trên một nhóm luồng (hoặc chỉ một luồng), vì vậy a. nó có thể phải đợi cho đến khi AsyncTaskkết thúc khác ; b . nó sẽ chiếm một chủ đề từ hồ bơi.
Pang

Có rất nhiều vấn đề khi sử dụng tác vụ async trong ngữ cảnh này (chỉ có một luồng và khóa luồng mà không có lý do) - các giải pháp khác tốt hơn nhiều.
tố

4

Tôi đang tạo một máy nghe nhạc mp3 cho Android, tôi muốn cập nhật thời gian hiện tại cứ sau 500ms vì vậy tôi đã làm nó như thế này

xác định

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

mà gọi cùng một phương thức đệ quy

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.