简体   繁体   English

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

[英]System.nanoTime() gives wrong times in Android

I am developing a game where some events happen after some predetermined amounts of time. 我正在开发一种游戏,其中一些事件发生在一段预定的时间之后。 For that I need to calculate how much time has elapsed from the starting of the game. 为此,我需要计算从游戏开始经过的时间。 I do that by launching a thread in the main loop and computing the time elapsed with System.nanoTime() . 我这样做是通过在主循环中启动一个线程并使用System.nanoTime()计算经过的时间。

I have tested the code on my smartphone and it works pretty well as long as I do not press the sleep button putting the phone in sleep (which triggers the onpause() method of the activity). 我已经在智能手机上测试了代码,只要我没有按下睡眠按钮将手机置于睡眠状态(触发活动的onpause()方法它就可以正常工作 But sometimes when I press the sleep button some very strange things: it seems that System.nanoTime() gives times greater than they actually are (never smaller by the way). 但有时当我按下睡眠按钮时会出现一些非常奇怪的事情:似乎System.nanoTime()给出的时间比它们实际上要大(顺便说一下,从不小)。

I have tried using System.currentTimeMillis() in place of System.nanoTime() but things are even worse (I know that there was some issues with System.nanoTime() on Windows systems with multi-core devices; by the way my smartphone is also multi-core). 我已经尝试使用System.currentTimeMillis()代替System.nanoTime()但事情更糟(我知道在具有多核设备的Windows系统上System.nanoTime()存在一些问题;顺便说一下我的智能手机也是多核的)。

Here is the code: 这是代码:

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;
            }
         }
      }
   }
}

Here is a normal output when I do not press the sleep button: 当我不按下睡眠按钮时,这是正常输出:

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 

And here is an anomalous output when I pressed the sleep button after 3 seconds and repressed again after some seconds. 当我在3秒钟后按下睡眠按钮并在几秒钟后再次压制时,这是一个异常输出。 (The anomalous behavior is from 4 to 6) As you can see, after less than 4 seconds have passed System.nanoTime() reports 6 seconds instead. (异常行为从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

How can I modify my code to avoid this behavior? 如何修改代码以避免此行为?

SystemClock is the appropriate clock to use on android SystemClock是在android上使用的合适时钟

Specifically SystemClock.elapsedRealtime() gives the time since the system was booted which (unlike System.currentTimeMillis() ) isn't affected by hour changes/user action and (unlike uptimeMillis() ) includes time in deep sleep 具体来说, SystemClock.elapsedRealtime()给出了自系统启动以来的时间(与System.currentTimeMillis()不同System.currentTimeMillis()不受小时更改/用户操作的影响,并且(与uptimeMillis()不同,包括深度睡眠时间)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Android中System.nanoTime()返回什么? - What does System.nanoTime() return in Android? Android:检查System.nanoTime的值 - Android: check value of System.nanoTime System.nanotime() 的安全时间来源 - Safe time origin for System.nanotime() NDK 应用程序的 System.nanoTime() 等价物? - Equivalent of System.nanoTime() for NDK apps? System.Nanotime给出负数 - System.nanotime giving negative numbers 为什么将System.nanoTime()转换为Calendar对象会给我错误的当前日期? - Why does converting System.nanoTime() to a Calendar object give me the wrong current date? Android:深度睡眠的时间间隔(System.nanoTime(),System.currentTimeMillis(),SystemClock.elapsedRealtimeNanos()) - Android: time intervals with deep sleep (System.nanoTime(), System.currentTimeMillis(), SystemClock.elapsedRealtimeNanos()) 将“ SensorEvent.timestamp”与“ System.nanoTime()”或“ SystemClock.elapsedRealtimeNanos()”同步 - Synchronizing “SensorEvent.timestamp” with “System.nanoTime()” or “SystemClock.elapsedRealtimeNanos()” Java System.nanoTime()经过时间的巨大差异 - Java System.nanoTime() huge difference in elapsed time Java计时,System.nanoTime()比System.currentTimeMillis()更糟糕,但它是否会在睡眠中持续存在? - Java timing, System.nanoTime() batter than System.currentTimeMillis() but does it persist over sleep?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM