在android中,在精确的n毫秒后重复一个任务
我的要求是每n毫秒对安卓传感器数据进行采样 尝试使用在android中,在精确的n毫秒后重复一个任务,android,timer,Android,Timer,我的要求是每n毫秒对安卓传感器数据进行采样 尝试使用计时器、报警管理器和处理程序。任务正在重复,但持续时间不是精确的n毫秒 代码:: 处理: Handler sensorHandler = new Handler(); private Runnable sensorRunnable = new Runnable() { @Override public void run() { sendAllSensorData();
计时器
、报警管理器
和处理程序
。任务正在重复,但持续时间不是精确的n毫秒
代码::
处理:
Handler sensorHandler = new Handler();
private Runnable sensorRunnable = new Runnable() {
@Override
public void run() {
sendAllSensorData();
sensorHandler.postDelayed(sensorRunnable, 50);
}
};
private void postSensorMsgHandler() {
sensorHandler.postDelayed(sensorRunnable, 50);
}
计时器::
私有void initTimer(){
定时器=新定时器()
}
日志::
06-22 15:34:53.201 D/Telemetric(27434): Telemetric Gyroscope Y mean = -0.000533 sd = 0.000958 variance = 0.000001
06-22 15:34:53.212 D/Telemetric(27434): Telemetric Gyroscope Y mean = 0.001057 sd = 0.000000 variance = 0.000000
06-22 15:34:53.253 D/Telemetric(27434): Telemetric Gyroscope Y mean = 0.000524 sd = 0.000754 variance = 0.000001
06-22 15:34:53.264 D/Telemetric(27434): Telemetric Gyroscope Y mean = -0.000009 sd = 0.001066 variance = 0.000001
06-22 15:34:53.306 D/Telemetric(27434): Telemetric Gyroscope Y mean = 0.000524 sd = 0.001376 variance = 0.000002
06-22 15:34:53.317 D/Telemetric(27434): Telemetric Gyroscope Y mean = 0.000844 sd = 0.001390 variance = 0.000002
06-22 15:34:53.361 D/Telemetric(27434): Telemetric Gyroscope Y mean = 0.000702 sd = 0.001291 variance = 0.000002
06-22 15:34:53.370 D/Telemetric(27434): Telemetric Gyroscope Y mean = 0.000600 sd = 0.001209 variance = 0.000001
06-22 15:34:53.414 D/Telemetric(27434): Telemetric Gyroscope Y mean = 0.000391 sd = 0.001266 variance = 0.000002
06-22 15:34:53.423 D/Telemetric(27434): Telemetric Gyroscope Y mean = 0.000465 sd = 0.001205 variance = 0.000001
试试这个
//Create Timer Object
Timer t = new Timer();
//Set your schedule time
t.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
//Called each time when 1000 milliseconds (1 second)
}
},
//Set start timing (milliseconds)
0,
//Set interval time(milliseconds)
1000);
Android不是一个“实时操作系统”,要获得你想要的高精度,你可能需要另一个硬件,例如一些嵌入式的,比如Raspberry。。。还有另一种操作系统,例如一些“实时Linux”
为什么不使用Android框架的常规传感器轮询机制呢
您可以使用这样的方法:在线程
run()
方法的循环中进行工作,并计算它的持续时间(比如工作持续时间
),而不是睡眠时间50000000-工作持续时间
(其中50000000是50毫秒,单位为纳秒),然后继续循环:
...
new Thread(new Runnable() {
@Override
public void run() {
try {
while (true) {
long startTime = System.nanoTime();
// do your work here
long workEndTime = System.nanoTime();
long workDuration = workEndTime - startTime;
long timeToSleep = 50000000 - workDuration;
long timeToSleepMillis = timeToSleep / 1000000;
int timeToSleepNanos = (int) (timeToSleep % 1000000);
Thread.sleep(timeToSleepMillis, timeToSleepNanos);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
...
当然,任务重复的持续时间不是精确的n毫秒,而是非常接近n(取决于当前设备)。此外,您还可以稍微调整
timeToSleep
值,以获得更精确的睡眠时间。如果您希望在某个确切时间运行一些Runnable
,请使用Handler\posttime
methodHandler sensorHandler=new Handler();private Runnable sensorRunnable=new Runnable(){@Override public void run(){Logger.d(“处理程序计时器::”+System.currentTimeMillis());sendAllSensorData();sensorHandler.posttime(sensorRunnable,SystemClock.uptimeMillis()+50);};private void postSensorMsgHandler(){sensorHandler.posttime(sensorRunnable,SystemClock.uptimeMillis()+50);}这是我的posttime代码。同一结果处理程序计时器::1498126539758处理程序计时器::1498126539782您要传递给posttime
的long uptimeMillis
值是多少?自系统启动以来,uptimeMillis以毫秒计。我的意思是您传递的确切值是多少,以及运行Runnable
时,这两个时间戳的区别是什么?感谢Manoj的回答,我的用例旨在实现毫秒级的粒度。如果我用1秒,它就可以正常工作。知道吗?好的意思是它在几毫秒内不工作?请尝试此代码并放置毫秒。我用问题粘贴的代码具有计时器任务,其中TelemetricConstant.delay为0,TelemetricConstant.SAMPLE_周期为50。registerListener中的samplingPeriodUs参数不保证精确时间。它只是根据文档对系统的提示。我试过这个。同样的结果。samplingPeriodUs int:两个连续事件之间所需的延迟,以微秒为单位。这只是对系统的一个提示。接收事件的速度可能快于或慢于指定的速率。通常情况下,事件接收速度很快。您不能期望任何框架计时器的粒度小于16ms,实际上,您甚至不能期望这些计时器将为相同的参数保持相同的间隔(从长远来看,它们可能会在统计上与参数保持接近)。如果您真的需要精确的计时,那么就使用本机和平台硬件计时器。已经有人说过,Android不是一个实时系统,它试图通过分批处理多个应用程序/线程要完成的工作来优化性能和功耗,而不需要过多地切换硬件的功率级别。
...
new Thread(new Runnable() {
@Override
public void run() {
try {
while (true) {
long startTime = System.nanoTime();
// do your work here
long workEndTime = System.nanoTime();
long workDuration = workEndTime - startTime;
long timeToSleep = 50000000 - workDuration;
long timeToSleepMillis = timeToSleep / 1000000;
int timeToSleepNanos = (int) (timeToSleep % 1000000);
Thread.sleep(timeToSleepMillis, timeToSleepNanos);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
...