简述:
Android开发中经常会遇到计算时间间隔的场景,Java语言中提供了几种计算时间的方法:System.currentTimeMillis()和SystemClock.uptimeMillis()。那么他们之间有什么区别呢?使用的时候会遇到什么样的“坑”呢?今天梳理一下。
分析:
既然是计算时间间隔,那么我们建立模型:
intervalTime(时间间隔) = startTime(起始时间) - endTime(终止时间);
那么现在需要的是startTime和endTime的获取。获取的方法采用2中:System.currentTimeMillis() 和 SystemClock.uptimeMillis()。
1、System.currentTimeMillis()
Android官方给出的解析为(链接:https://developer.android.com/reference/android/os/SystemClock.html):
System.currentTimeMillis() is the standard "wall" clock (time and date) expressing milliseconds since the epoch.
The wall clock can be set by the user or the phone network (see setCurrentTimeMillis(long)), so the time may jump backwards
or forwards unpredictably. This clock should only be used when correspondence with real-world dates and times is important,
such as in a calendar or alarm clock application. Interval or elapsed time measurements should use a different clock. If you
are using System.currentTimeMillis(), consider listening to the ACTION_TIME_TICK, ACTION_TIME_CHANGED and ACTION_TIMEZONE_CHANGED
Intent broadcasts to find out when the time changes.
上面的文档可以了解到:System.currentTimeMillis() 方法产生一个标准的自1970年1月1号0时0分0秒所差的毫秒数。该时间可以通过调用setCurrentTimeMillis(long)方法来手动设置,也可以通过网络来自动获取。
⭐️大坑
System.currentTimeMillis()得到的毫秒数为“1970年1月1号0时0分0秒-----》当前手机系统的时间”的差。因此如果在执行intervalTime(时间间隔)的值期间用户更改了手机系统的时间,那么得到的结果是不可预料的。
结论:它不适合用在需要时间间隔的地方,如Thread.sleep, Object.wait等,因为可以通过System.setCurrentTimeMillis来改变它的值。
2、SystemClock.uptimeMillis()
先来了解一下这个方法:
uptimeMillis() is counted in milliseconds since the system was booted. This clock stops when the system enters deep
sleep (CPU off, display dark, device waiting for external input), but is not affected by clock scaling, idle, or
other power saving mechanisms. This is the basis for most interval timing such as Thread.sleep(millls),
Object.wait(millis), and System.nanoTime(). This clock is guaranteed to be monotonic, and is suitable for interval
timing when the interval does not span device sleep. Most methods that accept a timestamp value currently expect
the uptimeMillis() clock.
大致意思说,SystemClock.uptimeMillis()方法用来计算自开机启动到目前的毫秒数。如果系统进入了深度睡眠状态(CPU停止运行、显示器息屏、等待外部输入设备)该时钟会停止计时,但是该方法并不会受时钟刻度、时钟闲置时间亦或其它节能机制的影响。因此SystemClock.uptimeMillis()方法也成为了计算间隔的基本依据,比如Thread.sleep()、Object.wait()、System.nanoTime()以及Handler都是用SystemClock.uptimeMillis()方法。这个时钟是保证单调性,适用于计算不跨越设备的时间间隔。目前大多数方法接受一个时间戳值uptimeMillis()的时钟。
结论:SystemClock.uptimeMillis()适用于计算适合用在需要时间间隔的地方。