Android开发之获取手机运行时间

前言

昨天我碰到一个问题,需要判断两次的时间,我当时的第一反应是用System.currentTimeMillis()来判断,最后发现这样会有一个BUG,那就是用户如果手动修改时间,那就全乱套了,于是我想有没有一个时间是只增加不减少,并且用户是不能修改的?一查,发现还真有,主要和SystemClock有关,接下来对这个类进行学习。

SystemClock

三种时钟都是有效的,它们不应该被混淆:

  1. System.currentTimeMillis()是一个标准的“墙”时钟(时间和日期),表示从纪元到现在的毫秒数。该墙时钟能够被用户或电话网络(见setCurrentTimeMillis(long))设置,所以该时间可能会向前或向后不可预知地跳越。该时钟应该仅仅被使用在当现实世界对应的日期和时间非常重要的情况下,比如日历或闹钟应用程序。而间隔时间和经历时间的测算应该使用不同的时钟。如果你使用System.currentTimeMillis(),当时间变化时时可以考虑监听ACTION为ACTION_TIME_TICK、ACTION_TIME_CHANGED和ACTION_TIMEZONE_CHANGED的广播。

  2. uptimeMillis()表示自系统启动时开始计时,以毫秒为单位。返回的是从系统启动到现在这个过程中的处于非休眠期的时间。当系统进入深度睡眠时(CPU关闭,设备变黑,等待外部输入装置)该时钟会停止。但是该时钟不会被时钟调整、闲置或其他节能机制所影响。这是大多数间隔时间的基本点,例如Thread.sleep(millls)、Object.wait(millis)和System.nanoTime()。该时钟被保证是单调的,适用于检测不包含休眠的间隔时间的情况。大多数接受一个时间戳值的方法认为是使用了uptimeMillis()时钟。

  3. elapsedRealtime() 和elapsedRealtimeNanos() 返回系统启动到现在的时间,包含设备深度休眠的时间。该时钟被确保单调,即使CPU在省电模式下,该时间也会继续计时。该时钟可以被使用在测量时间间隔时系统可能睡眠的时间段。

这有一些机制为了控制定时事件的:

  1. 标准的功能Thread.sleep(millis)Object.wait(millis)都总是合适的。这是功能使用uptimeMillis()时钟;如果该设备进入睡眠,剩余的时间将被推迟直到系统唤醒。这些同步功能可能被中断伴随Thread.interrupt()方法,并且你必须处理InterruptedException异常。

  2. SystemClock.sleep(millis)是一种实用工具函数变化类似于Thread.sleep(millis),但是它忽视了InterruptedException异常。使用该函数产生的延迟如果你不使用Thread.interrupt(),因为它会保存线程的中断状态。

  3. 处理程序类可以安排在绝对或相对时间异步回调。处理器类对象也使用uptimeMillis()时钟,并且需要一个eventloop(正常呈现在任何一个GUI应用程序上)。该AlarmManager可以触发一次或重复事件去发生即使在深睡眠或你的应用程序没有运行。事件可能有计划的发生伴随你的currentTimeMillis()(RTC)机会或elapsedRealtime()(ELAPSED_REALTIME),并且引起一个意图广播当它们发生时。

有几种机制可以控制事件发生的时间:

  1. 对标准的方法比如Thread.sleep(millis) 和Object.wait(millis)都是有效的,这些方法使用的是uptimeMillis()时钟,如果设备进入深度休眠,剩余的时间将被推迟直到系统唤醒。这些同步方法可能被Thread.interrupt()中断,你必须处理InterruptedException异常。

  2. SystemClock.sleep(millis)是一个类似于Thread.sleep(millis)的实用方法,但是它忽略InterruptedException异常(其实就是使用Thread.sleep,不过对异常进行了处理)。使用该函数会产生延迟,如果你不使用Thread.interrupt(),因为它会保存线程的中断状态。

  3. Handler类可以在一个相对或者绝对的时间设置异步回调,Handler对象也使用uptimeMillis()时钟,而且需要一个loop(经常出现在GUI程序中)。

  4. AlarmManager可以触发一次或重复事件,即使设备深度休眠或者应用程序没有运行。事件可以选择用currentTimeMillis()(RTC)或者elapsedRealtime()(ELAPSED_REALTIME)来设置时间,当事件发生会触发一个Intent广播。

  5. public方法:

static long currentThreadTimeMillis() 返在当前线程运行的毫秒数。

static long elapsedRealtime() 返回系统启动到现在的毫秒数,包含休眠时间。

static long elapsedRealtimeNanos() 返回系统启动到现在的纳秒数,包含休眠时间。

static boolean setCurrentTimeMillis(long millis) 设置当前挂钟时间,以毫秒为单位。需要调用进程具有相应的权限。

static void sleep(long ms) 等待给定的时间(uptimeMillis)。和Thread.sleep(millis)类似,但是它不会抛出InterruptedException异常。事件被推迟到下一个中断操作。该方法直到指定的时间过去才返回。

static long uptimeMillis() 返回系统启动到现在的毫秒级时间,不包含休眠时间。(系统启动到现在的非休眠期时间)

猜你喜欢

转载自my.oschina.net/u/268088/blog/1647965
今日推荐