4

我想在特定时间开始一项任务。为此,我使用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 TASKdesiredHourdesiredMinute0 秒开始。然而,“我的任务以几秒钟的延迟开始,看起来是随机的。

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

谢谢

4

3 回答 3

6

首先,您的延迟计算是正确的,但是“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可以替代吗?

于 2011-07-18T07:35:04.200 回答
0

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

Handler 似乎真的是为在活动活动中更新 GUI 而设计的,而不是在很远的将来安排任务。正如 scessor 所说,AlarmManager 可能是您最好的选择。

于 2011-10-06T20:00:38.410 回答
0

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

根据可以在此处看到的文档,可以看出 该类专门用于将来运行任务。

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

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

于 2012-01-29T18:22:38.487 回答