问题
我有一个Map<Long, String>
我需要启动一个计时器,并且当时间(以毫秒为单位)与Map中的任何键匹配时,它应该将其值附加到TextView。
我尝试过的事情
我已经尝试实现 Timer 和 Handler ,但是由于它们都使用Threads,因此输出被错误排列。
new Timer().scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
if (map.containsKey(elapsed)) {
textView.append(map.get(elapsed));
}
}
});
elapsed++;
}
}, 0, 1);
我需要的
一种无需使用线程即可完成的方法。这里的主要问题是因为代码必须每毫秒执行一次,线程混乱并且字符排列不正确。有什么有效的方法可以达到预期的结果吗?
答案 0 :(得分:2)
首先-如果您希望每毫秒运行一次,请找到其他操作系统。 Android(以及Linux中的gneneral)并未针对此类操作进行优化。您确实需要一个RTOS,以确保能够正常工作。 Linux的sleep命令甚至不接受很小的参数,因此默认为no-op。
其次-您可能实际上并不希望它每毫秒运行一次。几乎可以肯定,您在估计其完成频率上的工作量很大。
第三-您正在编写UI。 UI仅以最大速率每1/60秒更新一次。因此,即使您以1ms的速度运行它,也不会每秒执行超过60次(约16ms)的操作。
第四-答案是线程。非线程-单线程。这会运行一次while循环,在两次尝试之间睡眠一毫秒(尽管睡眠1毫秒可能只是立即返回,或者以系统的任何计时器频率返回,可能为16毫秒)。但是,您不希望每个请求一个线程,而是想要一个线程周期,因此尝试是同步发生的,并且不依赖于线程调度。
但是真正的答案是,您做事的方式是错误的,应该从另一个方向来对待事情。
答案 1 :(得分:0)
有两种方法可以实现此目的:
使用处理程序:使用处理程序不一定需要创建另一个线程。您可以创建一个处理程序以使用UI线程的looper / messagequeue,并通过延迟所需的任何时间来继续对其调用“ postDelayed”。
使用AlarmManager:您可以使用“ setRepeating”来安排重复发送的PendingIntent。请注意,AlarmManager在API 19之后仍然不是精确的