System.nanoTime()在Android中给出了错误的时间

System.nanoTime()在Android中给出了错误的时间,android,multithreading,sleep,nanotime,Android,Multithreading,Sleep,Nanotime,我正在开发一个游戏,其中一些事件发生在预定的时间之后。为此,我需要计算从游戏开始到现在已经过去了多少时间。我通过在主循环中启动一个线程并使用System.nanoTime()计算经过的时间来实现这一点 我已经在我的智能手机上测试了该代码,只要我不按下睡眠按钮使手机进入睡眠状态(这会触发活动的onpause()方法),它就可以正常工作。但有时当我按下sleep按钮时,会出现一些非常奇怪的情况:似乎System.nanoTime()给出的时间比实际的时间长(顺便说一句,从来没有小过) 我曾尝试使用S

我正在开发一个游戏,其中一些事件发生在预定的时间之后。为此,我需要计算从游戏开始到现在已经过去了多少时间。我通过在主循环中启动一个线程并使用System.nanoTime()计算经过的时间来实现这一点

我已经在我的智能手机上测试了该代码,只要我不按下睡眠按钮使手机进入睡眠状态(这会触发活动的onpause()方法),它就可以正常工作。但有时当我按下sleep按钮时,会出现一些非常奇怪的情况:似乎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;
            }
         }
      }
   }
}
这是一个异常的输出,当我在3秒钟后按下睡眠按钮,几秒钟后再次按下。(异常行为从4到6)如您所见,在系统运行不到4秒后,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
如何修改代码以避免这种行为?

是否适合在android上使用时钟


具体来说,
SystemClock.elapsedRealtime()
给出了自系统启动以来的时间,该时间(与
system.currentTimeMillis()
不同)不受小时变化/用户操作的影响,并且(与
uptimeMillis()
不同)包含深度睡眠时间

谢谢您的回答。SystemClock计算自引导以来经过的时间;有没有办法从任意事件计算时间?@CHebdo Well System.currentTimeMillis()将给出自1970年1月1日以来的毫秒数,但当用户手动更改系统时钟时,可以跳转。您必须获得自系统重新启动/关闭之前发生事件以来的时间吗?我尝试过system.currentTimeMillis(),但它提供了比system.nanoTime()更奇怪的行为@CHebdo奇怪的是什么方式?你不能在开始时间缓存系统时钟读数并将其与当前读数进行比较吗?看来你正忙于在后台线程中循环,这样做会在一个小时左右后耗尽电池。。。
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