Android 中的时间

最近项目中遇到一个上报时间错误的问题。查了一段时间,中间一度怀疑是否是用户修改时间造成的计算错误。然后就了解了一下Android系统中所使用的时间。其实谷歌已经为我们整理了一份文档并做了区分。可以翻墙的同学直接参考 这里。这里还是根据自己的理解与经验做一些解读。

System.currentTimeMillis()

我们一般通过它来获取手机系统的当前时间。事实上,它返回的值是系统时刻距离标准时刻(1970.01.01 00:00:00)的毫秒数。它相当于家里的“挂钟”一样,并不是十分精准,而且可以随意修改。所以它可能经常被网络或者用户校准。正是由于这个原因,这个方法获取的值不适合用来做时间间隔的统计。但是它适合用来获取当前日期,时刻等时间点相关的逻辑。

SystemClock.upTimeMillis()

这个值记录了系统启动到当前时刻经过的时间。但是系统深度睡眠(CPU睡眠,黑屏,系统等待唤醒)之中的时间不算在内。这个值不受系统时间设置,电源策略等因素的影响,因此它是大多数时间间隔统计的基础,例如Thread.sleep(long millis),Object.wait(long millis),System.nanoTime()等。系统保证了这个值只增长不下降,所以它适合所有的不包括系统睡眠时间的时间间隔统计

SystemClock.elapsedRealtime() & SystemClock.elapsedRealtimeNanos

这个值与SystemClock.upTimeMillis()类似。它是系统启动到当前时刻经过的时间,包括了系统睡眠经过的时间。在CPU休眠之后,它依然保持增长。所以它适合做更加广泛通用的时间间隔的统计

综上,如果想要避免用户修改时间,网络校准时间对时间间隔统计的影响,使用SystemClock类相关的方法就可以了,至于选择upTimeMillis()还是elapsedRealtime()就要根据自己的需求确定了。

系统还提供了几个时间控制相关的工具:

  1. 标准方法Thread.sleep(long millis)Object.wait(long millis)是基于SystemClock.upTimeMillis()的。所以在系统休眠之后它们的回调也会延期,直到系统被唤醒才继续计时。并且这两个同步方法会响应InterruptException,所以在使用它们的时候必须要处理InterruptException异常。
  2. SystemClock.sleep(long millis)Thread.sleep(long millis) 方法是类似的,只不过SystemClock.sleep(long millis) 不响应InterruptException异常。
  3. Handler类的 postDelay()方法也是基于SystemClock.upTimeMillis()方法的。
  4. AlarmManager可以定时发送消息,即使在系统睡眠、应用停止的状态下也可以发送。我们在创建定时事件的时候有两个参数可以选择RTCELAPSED_REALTIME,它们对应的方法就是System.currentTimeMillis() ~ RTCSystemClock.elapsedRealtime() ~ ELAPSED_REALTIME。这样一对应,它们的区别也就非常明显了。

参考文章:

https://developer.android.com/reference/android/os/SystemClock.html

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏企鹅号快讯

Spring编程式事务处理不当引起的连接泄露事件

某一日正在孜孜不倦的研究代码,忽然测试童鞋说系统服务挂了,完全不可用。 程序大量抛出如下异常: 对于程序员来说,系统宕机就是军令,更可况是难得一见的连接池泄露问...

31060
来自专栏web前端教室

继续电商网站的购物车

这一阶段的内容会比较枯燥,没办法啊。纯业务逻辑这块,写不出情趣来。有兴趣的就耐着性子看看,没耐性的可以等等看,改天写个有趣的内容之类的 我这个简单的购物车从功能...

44370
来自专栏木子昭的博客

<scapy>刺探星巴克无线网,记录顾客信息

上网除了需要IP, 还需要Mac地址, Mac与网卡绑定, 记录了设备的Mac, 相当于标记了设备使用者 关于Mac和IP的关系: <讲个故事>为什么IP地址...

39160
来自专栏哲学驱动设计

Rafy 领域实体框架示例(1) - 转换传统三层应用程序

Rafy 领域实体框架发布后,虽然有帮助文档,许多朋友还是反映学习起来比较复杂,希望能开发一个示例程序,展示如何使用 Rafy 领域实体框架所以,本文通过使用 ...

21850
来自专栏Android相关

处理器结构--PipeLine&SuperScalar

最初开始,指令一条一条顺序执行,后来当工艺进步了,CPU中的元件越来越多,而在原来的顺序执行的过程中,只有一条指令的某一个阶段在执行,如取指,取数据等等,其他元...

16050
来自专栏Java架构

JAVA程序员怎么样才能进一线互联网公司

2.做过哪些项目?项目中遇到哪些难点,你是怎样解决的?单点登录系统说一下?分布式缓存的使用场景?(说好的基础呢,上来就是项目,毫无准备,导致好多东西都记不起来了...

21920
来自专栏xingoo, 一个梦想做发明家的程序员

云计算学习2

4 网络加密 VPN virtual private network 虚拟个人网络:长连接和加密 L2TP(layer 2 tunneling protocol...

25480
来自专栏进击的程序猿

The Clean Architecture in PHP 读书笔记(六)之你不知道的MVCMVC和其的局限性

前面介绍了一些基础内容,涉及到了去耦的5大工具,本章开始讲介绍本书的重点:Clean Architecture,Clean Architecture通过我们之前...

11120
来自专栏熊二哥

《大型分布式网站架构》学习笔记--01SOA

"学无长幼,达者为先",作者陈康贤通过3年左右时间就能写出如此著作确实令人钦佩,加油,熊二,早日成为一个合格的后端程序员。 基础概念 SOA(Service-O...

235100
来自专栏北京马哥教育

怎么制定一套合适的服务器命名方案

在MNX上,我们一直致力于为我们的云托管服务建立一个全新的数据中心。起初我们是一家提供管理Linux服务的咨询公司,这也就意味着我们将置身于大量的不同用户环境,...

61040

扫码关注云+社区

领取腾讯云代金券