使用 postDelayed 在特定时间运行任务

发布于 2024-11-24 20:13:57 字数 1313 浏览 1 评论 0原文

我想在特定时间开始一项任务。为此,我使用 runnablepostDelayed 方法,如下所示:

private Runnable mLaunchTask = new Runnable() {
        public void run() {

            try {
                MY TASK
            } catch (IllegalStateException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
};

在我的代码中,我使用 mLunchTask 如下:

mHandler = new Handler();
mHandler.postDelayed(mLaunchTask, myDelay*1000); 

myDelay计算如下:

s  = DateFormat.format("hh:mm:ss aaa", d.getTime());
cTime = s.toString(); // current Time
ch = Integer.parseInt(cTime.substring(0,2)); // current hour
cm = Integer.parseInt(cTime.substring(3,5)); // current minute
cs = Integer.parseInt(cTime.substring(6,8)); // current second
if (cTime.substring(9,11).equalsIgnoreCase("pm") && (ch<12) ) ch = ch+12; 
myDelay=(desiredHour-ch)*3600+(desiredMinute-cm)*60 - cs;
if (myDelay<0) myDelay = 0;

desiredHourdesiredMinute由用户设置。预期 MY TASKdesiredHourdesiredMinute 零秒处开始。 但是“我的任务启动有几秒钟的延迟,这看起来是随机的。

根据上面的代码,是否有任何原因导致它没有在所需的确切时间启动?

谢谢

I would like to start a task at a specific time. For that I use runnable and postDelayed method as follows:

private Runnable mLaunchTask = new Runnable() {
        public void run() {

            try {
                MY TASK
            } catch (IllegalStateException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
};

In my code I use mLunchTask as follows:

mHandler = new Handler();
mHandler.postDelayed(mLaunchTask, myDelay*1000); 

and myDelay is computed as follows:

s  = DateFormat.format("hh:mm:ss aaa", d.getTime());
cTime = s.toString(); // current Time
ch = Integer.parseInt(cTime.substring(0,2)); // current hour
cm = Integer.parseInt(cTime.substring(3,5)); // current minute
cs = Integer.parseInt(cTime.substring(6,8)); // current second
if (cTime.substring(9,11).equalsIgnoreCase("pm") && (ch<12) ) ch = ch+12; 
myDelay=(desiredHour-ch)*3600+(desiredMinute-cm)*60 - cs;
if (myDelay<0) myDelay = 0;

and desiredHour and desiredMinute are set by user. The expectation is that MY TASK starts at desiredHour and desiredMinute and 0 seconds.
However "MY TASK starts with a few seconds delay, which looks like is random.

Based on the above code, is there any reason that it does not start at the exact desired time?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

临走之时 2024-12-01 20:13:57

首先,您的延迟计算是正确的,但“pm”检测不适用于其他语言。最好使用日历来获取延迟:

Calendar calendar = Calendar.getInstance();
long currentTimestamp = calendar.getTimeInMillis();
calendar.set(Calendar.HOUR_OF_DAY, desiredHour);
calendar.set(Calendar.MINUTE, desiredMinute);
calendar.set(Calendar.SECOND, 0);
long diffTimestamp = calendar.getTimeInMillis() - currentTimestamp;
long myDelay = (diffTimestamp < 0 ? 0 : diffTimestamp);

现在您的延迟以毫秒为单位,并且可以启动处理程序:

new Handler().postDelayed(mLaunchTask, myDelay);

在我的测试中,以下可运行日志在所需的时间没有延迟。

private Runnable mLaunchTask = new Runnable() {
    public void run() {
        Calendar calendar = Calendar.getInstance();
        Log.d("test", "started at " 
            + calendar.get(Calendar.HOUR_OF_DAY) + " " 
            + calendar.get(Calendar.MINUTE) + " "
            + calendar.get(Calendar.SECOND)
        );
    }
};

也许您启动的任务需要几秒钟才能加载?

AlarmManager 可以作为替代方案吗?

First of all, your delay calculation is correct, but the "pm" detection doesn't work with other languages. It is much better to use the calendar to get the delay:

Calendar calendar = Calendar.getInstance();
long currentTimestamp = calendar.getTimeInMillis();
calendar.set(Calendar.HOUR_OF_DAY, desiredHour);
calendar.set(Calendar.MINUTE, desiredMinute);
calendar.set(Calendar.SECOND, 0);
long diffTimestamp = calendar.getTimeInMillis() - currentTimestamp;
long myDelay = (diffTimestamp < 0 ? 0 : diffTimestamp);

Now you have the delay in milli secs and can start the handler:

new Handler().postDelayed(mLaunchTask, myDelay);

In my test the following runnable logs at the desired time with no delay.

private Runnable mLaunchTask = new Runnable() {
    public void run() {
        Calendar calendar = Calendar.getInstance();
        Log.d("test", "started at " 
            + calendar.get(Calendar.HOUR_OF_DAY) + " " 
            + calendar.get(Calendar.MINUTE) + " "
            + calendar.get(Calendar.SECOND)
        );
    }
};

Maybe your started task needs some seconds to be loaded?

Could the AlarmManager be an alternative?

十二 2024-12-01 20:13:57

根据我的经验和阅读文档,postDelayed 基于正常运行时间,而不是实时。如果手机进入深度睡眠状态,可能会导致实时时间过去而不会增加正常运行时间。这意味着您的任务将比预期晚开始。

处理程序似乎确实是为更新活动活动中的 GUI 而设计的,而不是调度将来的任务。正如 scessor 所说,AlarmManager 可能是您最好的选择。

Based on my experience and reading of the documentation, postDelayed is based on uptime, not real time. If the phone goes into deep sleep, it can cause real time to pass without uptime incrementing. That means your task will start later than desired.

The Handler really seems to be designed for updating the GUI in an active activity, not scheduling tasks far in the future. As scessor said, AlarmManager is probably your best bet.

小姐丶请自重 2024-12-01 20:13:57

纳利巴的回答并不完全正确。

基于可以看到的文档 这里
可以看出这个类是专门用来以后运行任务的。

“处理程序有两个主要用途:(1) 安排消息和可运行对象在将来的某个时刻执行;(2) 将要执行的操作排入队列与您自己的线程不同。”

没有关于系统进入睡眠模式时应用程序行为的参考,应在发布其他信息之前测试此问题。

The Naliba's answer is not completely correct.

Based on documentation that can be seen here
it can be seen that this class is specifically used for running tasks in the future.

"There are two main uses for a Handler: (1) to schedule messages and runnables to be executed as some point in the future; and (2) to enqueue an action to be performed on a different thread than your own. "

There is no reference about the behavior of the application when the system enters in sleep mode and this issue should be tested before posting additional information.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文