我想在特定时间开始一项任务。为此,我使用runnable
和postDelayed
方法,如下所示:
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;
并且desiredHour
和desiredMinute
由用户设置。期望MY TASK
从desiredHour
和desiredMinute
开始,0秒。
然而,“我的任务开始时有几秒延迟,看起来像是随机的。
基于上面的代码,是否有任何理由不能在确切的时间开始?
由于
答案 0 :(得分:5)
首先,您的延迟计算是正确的,但“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可以替代吗?
答案 1 :(得分:0)
根据我的经验和阅读文档,postDelayed基于正常运行时间而非实时。如果手机进入深度睡眠状态,它可能导致实时通过而无需正常运行时间增加。这意味着您的任务将比预期更晚开始。
Handler似乎真的被设计用于在活动活动中更新GUI,而不是在将来安排任务。正如scessor所说,AlarmManager可能是你最好的选择。
答案 2 :(得分:0)
纳利巴的回答并不完全正确。
基于可以看到的文档here 可以看出,这个类专门用于将来运行任务。
“处理程序有两个主要用途:(1)安排消息和runnables作为将来的某个点执行;以及(2)将行动排入队列可以在与您自己不同的线程上执行。“
当系统进入睡眠模式时,没有关于应用程序行为的参考,应该在发布其他信息之前测试此问题。