我正在开发一种游戏,其中某些事件在一段预定的时间后发生。为此,我需要计算从游戏开始经过的时间。我这样做是通过在主循环中启动一个线程并使用 System.nanoTime()计算经过的时间。
我已经在我的智能手机上测试了代码,只要我没有按下睡眠按钮让手机进入睡眠状态(触发活动的 onpause()方法),它就可以正常工作。但有时当我按下睡眠按钮时会出现一些非常奇怪的事情:似乎 System.nanoTime()给出了比实际更大的时间(顺便说一下,从不小)。
我尝试使用 System.currentTimeMillis()代替 System.nanoTime(),但情况更糟(我知道存在一些问题>具有多核设备的Windows系统上的System.nanoTime();顺便说一句,我的智能手机也是多核的。)
以下是代码:
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class MainActivity extends Activity implements Runnable {
private Thread gameThread = null;
private volatile boolean running = false;
private long startTime;
private long totalTime;
private boolean[] afterNSeconds = new boolean[11];
private static long oneBillion = 1000000000;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView tv = new TextView(getApplicationContext());
tv.setText("Start");
setContentView(tv);
}
@Override
public void onResume() {
super.onResume();
running = true;
gameThread = new Thread(this);
gameThread.start();
}
@Override
public void onPause() {
super.onPause();
totalTime = System.nanoTime() - startTime;
running = false;
while (true) {
try {
gameThread.join();
return;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Override
public void run() {
startTime = System.nanoTime();
while (running) {
long elapsedTime = totalTime + System.nanoTime()
- startTime;
for (int j = 1; j <= 10; j++) {
if (elapsedTime >= j * oneBillion
&& !afterNSeconds[j]) {
Log.d("MainActivity", j + ": elapsedTime = "
+ elapsedTime );
afterNSeconds[j] = true;
}
}
}
}
}
当我不按下睡眠按钮时,这是正常输出:
01-07 23:56:40.722: D/MainActivity(26579): 1: elapsedTime = 1021247230
01-07 23:56:41.708: D/MainActivity(26579): 2: elapsedTime = 2007078538
01-07 23:56:42.701: D/MainActivity(26579): 3: elapsedTime = 3000023615
01-07 23:56:43.701: D/MainActivity(26579): 4: elapsedTime = 4000000538
01-07 23:56:44.701: D/MainActivity(26579): 5: elapsedTime = 5000000846
01-07 23:56:45.701: D/MainActivity(26579): 6: elapsedTime = 6000001230
01-07 23:56:46.701: D/MainActivity(26579): 7: elapsedTime = 7000001384
01-07 23:56:47.701: D/MainActivity(26579): 8: elapsedTime = 8000001923
01-07 23:56:48.701: D/MainActivity(26579): 9: elapsedTime = 9000000769
01-07 23:56:49.701: D/MainActivity(26579): 10: elapsedTime = 10000002000
当我在3秒钟后按下睡眠按钮并在几秒钟后再次压制时,这是一个异常输出。 (异常行为从4到6)正如您所看到的,在经过不到4秒后, System.nanoTime()报告的时间为6秒。
01-08 00:02:48.645: D/MainActivity(26579): 1: elapsedTime = 1001408231
01-08 00:02:49.644: D/MainActivity(26579): 2: elapsedTime = 2000000615
01-08 00:02:50.644: D/MainActivity(27265): 3: elapsedTime = 3000000539
01-08 00:02:50.802: D/MainActivity(27265): 4: elapsedTime = 6000000462
01-08 00:02:50.802: D/MainActivity(27265): 5: elapsedTime = 6000000462
01-08 00:02:50.802: D/MainActivity(27265): 6: elapsedTime = 6000000462
01-08 00:03:21.358: D/MainActivity(27265): 7: elapsedTime = 7000000770
01-08 00:03:22.358: D/MainActivity(27265): 8: elapsedTime = 8000000539
01-08 00:03:23.358: D/MainActivity(27265): 9: elapsedTime = 9000000154
01-08 00:03:23.730: D/MainActivity(27265): 10: elapsedTime = 10000003847
如何修改代码以避免此行为?
答案 0 :(得分:2)
SystemClock是在android
上使用的合适时钟具体而言SystemClock.elapsedRealtime()
给出了自系统启动以来的时间(与System.currentTimeMillis()
不同)不受小时更改/用户操作的影响(与uptimeMillis()
不同)包括时间深度睡眠