相当于Android / Java中的JavaScript setInterval / setTimeout?


Answers:


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

这是抽屉选择和fragmentTransaction一个很好的解决方案
贡萨洛

6
如果需要,如何取消它?
昆汀·罗伊,2016年

您如何在run()方法中获得活动范围?
安迪

@Andy像这样:MyActivityName.this.myFunctionOnActivity()
Ben Clayton

1
@QuentinRoy:Handler timeout = new Handler(); final Runnable r = new Runnable{...}; timeout.postDelayed(r, 300);如果要取消它:timeout.removeCallbacks(r);
Bastian Springer

101

setInterval()

每n毫秒重复一次的功能

Java脚本

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

仅在n毫秒后起作用的功能

Java脚本

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方法,一旦活动结束,如何在活动中取消计时器?
auroranil

2
@ user824294,您可以将Timer实例保存在变量中,并在要停止计划的任务时调​​用“ cancel()”-Timer t = new Timer(); t.scheduleAtFixedRate(...); -然后调用t.cancel(); 随时随地。
Aebsubis '17

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手机从睡眠模式中唤醒。换句话说,如果您希望即使屏幕关闭/ CPU处于睡眠状态也要安排一些实际发生的事情,则也需要签出AlarmManager。


5

我对JavaScript不太了解,但是我认为Timers可能就是您想要的。

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

从链接:

单发计划在绝对时间或相对延迟后运行。定期任务以固定的周期或固定的速率进行调度。


注意:它在后台线程而不是在main / UI线程上调用您。

这不是答案,而是对可能包含或可能不包含OP解决方案的外部信息的引用。请粘贴相关代码OP即可使用!
2014年

5

第一个答案绝对是正确的答案,也是我基于此lambda版本创建的,它的语法要短得多。由于Runnable只有1个覆盖方法“ run()”,我们可以使用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

这是等效的setTimeout,在尝试延迟后更新用户界面时最有用。

如您所知,只能通过UI线程来完成对用户界面的更新。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完成为止;b。它会占用池中的一个线程。

在这种情况下,使用异步任务存在很多问题(只有一个线程并且无缘无故地锁定了线程)-其他解决方案要好得多。
Elemental

4

我正在为Android创建一个mp3播放器,我想每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);
}

递归地调用相同的方法

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.