Android中各种Time API详细

 更新时间:2021年10月14日 16:00  点击:2014

1、时间API

为了跟踪性能,我们需要测量时间间隔,即两个时间点之间的差异。 JDK 为我们提供了两种获取当前时间的方法:

// Milliseconds since Unix epoch (00:00:00 UTC on 1 January 1970)
System.currentTimeMillis()
// Nanoseconds since the VM started.
System.nanoTime()

Android 提供了一个 SystemClock 类,它增加了一些:

// (API 29) Clock that starts at Unix epoch.
// Synchronized using the device's location provider.
SystemClock.currentGnssTimeClock()
// Milliseconds running in the current thread.
SystemClock.currentThreadTimeMillis()
// Milliseconds since boot, including time spent in sleep.
SystemClock.elapsedRealtime()
// Nanoseconds since boot, including time spent in sleep.
SystemClock.elapsedRealtimeNanos()
// Milliseconds since boot, not counting time spent in deep sleep.
SystemClock.uptimeMillis()

我们应该选择哪一个? SystemClock javadoc 有助于回答这个问题:

System#currentTimeMillis 可以由用户或电话网络设置,因此时间可能会不可预测地向后或向前跳跃。 间隔或经过时间测量应使用不同的时钟。

SystemClock#uptimeMillis 在系统进入深度睡眠时停止。 这是大多数间隔计时的基础,例如 Thread#sleep(long) Object#wait(long) System#nanoTime。 当间隔不跨越设备休眠时,该时钟适用于间隔计时。

SystemClock#elapsedRealtime SystemClock#elapsedRealtimeNanos 包括深度睡眠。 该时钟是通用间隔计时的推荐基础。

应用程序的性能对深度睡眠中发生的事情没有影响,所以我们最好的选择是 SystemClock.uptimeMillis() System.nanoTime()

2、uptimeMillis() vs nanoTime()

System.nanoTime() uptimeMillis() 更精确,但这仅对微基准测试有用。 在生产中跟踪性能时,我们需要毫秒级的分辨率。

让我们比较一下它们的性能影响。 我克隆了 Android Benchmark Samples 存储库并添加了以下测试:

@LargeTest
@RunWith(AndroidJUnit4::class)
class TimingBenchmark {
    @get:Rule
    val benchmarkRule = BenchmarkRule()

    @Test
    fun nanoTime() {
        benchmarkRule.measureRepeated {
            System.nanoTime()
        }
    }

    @Test
    fun uptimeMillis() {
        benchmarkRule.measureRepeated {
            SystemClock.uptimeMillis()
        }
    }
}

在运行 Android 10 的 Pixel 3 上的结果:

System.nanoTime() 中值时间:208 ns

SystemClock.uptimeMillis() 中值时间:116 ns

SystemClock.uptimeMillis() 几乎快两倍! 虽然这种差异应该不会对应用程序产生任何有意义的影响,但我们能弄清楚为什么它要快得多吗?

3、uptimeMillis() 实现

SystemClock.uptimeMillis() 实现为带有@CriticalNative 注释的本机方法。 CriticalNative 为不包含对象的方法提供更快的 JNI 转换。

public final class SystemClock {
    @CriticalNative
    native public static long uptimeMillis();
}

原生实现在 SystemClock.c++ 中:

int64_t uptimeMillis()
{
    int64_t when = systemTime(SYSTEM_TIME_MONOTONIC);
    return (int64_t) nanoseconds_to_milliseconds(when);
}

systemTime() 在 Timers.cpp 中定义:

nsecs_t systemTime(int clock) {
    static constexpr clockid_t clocks[] = {
        CLOCK_REALTIME,
        CLOCK_MONOTONIC,
        CLOCK_PROCESS_CPUTIME_ID,
        CLOCK_THREAD_CPUTIME_ID,
        CLOCK_BOOTTIME
    };
    timespec t = {};
    clock_gettime(clocks[clock], &t);
    return nsecs_t(t.tv_sec)*1000000000LL + t.tv_nsec;
}

4、nanoTime() 实现

System.nanoTime() 也被实现为带有@CriticalNative 注释的本地方法。

public final class System {
    @CriticalNative
    public static native long nanoTime();
}

本地实现在 System.c 中:

static jlong System_nanoTime() {
  struct timespec now;
  clock_gettime(CLOCK_MONOTONIC, &now);
  return now.tv_sec * 1000000000LL + now.tv_nsec;
}

这两个实现其实很相似,都调用clock_gettime()

事实证明,@CriticalNative 最近才被添加到 System.nanoTime() ,这就解释了为什么它变慢了!

结论:

在生产应用中跟踪性能时:

对于大多数用例,毫秒分辨率就足够了。 要测量时间间隔,请使用 SystemClock.uptimeMillis() System.nanoTime() 。 后者在较旧的 Android 版本上速度较慢,但这在这里无关紧要。

到此这篇关于Android中各种Time API详细的文章就介绍到这了,更多相关Android中各种Time API内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!

[!--infotagslink--]

相关文章

  • Android子控件超出父控件的范围显示出来方法

    下面我们来看一篇关于Android子控件超出父控件的范围显示出来方法,希望这篇文章能够帮助到各位朋友,有碰到此问题的朋友可以进来看看哦。 <RelativeLayout xmlns:an...2016-10-02
  • Android开发中findViewById()函数用法与简化

    findViewById方法在android开发中是获取页面控件的值了,有没有发现我们一个页面控件多了会反复研究写findViewById呢,下面我们一起来看它的简化方法。 Android中Fin...2016-09-20
  • Android模拟器上模拟来电和短信配置

    如果我们的项目需要做来电及短信的功能,那么我们就得在Android模拟器开发这些功能,本来就来告诉我们如何在Android模拟器上模拟来电及来短信的功能。 在Android模拟...2016-09-20
  • 夜神android模拟器设置代理的方法

    夜神android模拟器如何设置代理呢?对于这个问题其实操作起来是非常的简单,下面小编来为各位详细介绍夜神android模拟器设置代理的方法,希望例子能够帮助到各位。 app...2016-09-20
  • android自定义动态设置Button样式【很常用】

    为了增强android应用的用户体验,我们可以在一些Button按钮上自定义动态的设置一些样式,比如交互时改变字体、颜色、背景图等。 今天来看一个通过重写Button来动态实...2016-09-20
  • Android WebView加载html5页面实例教程

    如果我们要在Android应用APP中加载html5页面,我们可以使用WebView,本文我们分享两个WebView加载html5页面实例应用。 实例一:WebView加载html5实现炫酷引导页面大多...2016-09-20
  • WebStorm无法正确识别Vue3组合式API的解决方案

    这篇文章主要介绍了WebStorm无法正确识别Vue3组合式API的解决方案,帮助大家更好的理解和学习使用vue框架,感兴趣的朋友可以了解下...2021-02-18
  • 深入理解Android中View和ViewGroup

    深入理解Android中View和ViewGroup从组成架构上看,似乎ViewGroup在View之上,View需要继承ViewGroup,但实际上不是这样的。View是基类,ViewGroup是它的子类。本教程我们深...2016-09-20
  • Android自定义WebView网络视频播放控件例子

    下面我们来看一篇关于Android自定义WebView网络视频播放控件开发例子,这个文章写得非常的不错下面给各位共享一下吧。 因为业务需要,以下代码均以Youtube网站在线视...2016-10-02
  • 浅谈vue2的$refs在vue3组合式API中的替代方法

    这篇文章主要介绍了浅谈vue2的$refs在vue3组合式API中的替代方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-04-18
  • Android用MemoryFile文件类读写进行性能优化

    java开发的Android应用,性能一直是一个大问题,,或许是Java语言本身比较消耗内存。本文我们来谈谈Android 性能优化之MemoryFile文件读写。 Android匿名共享内存对外A...2016-09-20
  • Android设置TextView竖着显示实例

    TextView默认是横着显示了,今天我们一起来看看Android设置TextView竖着显示如何来实现吧,今天我们就一起来看看操作细节,具体的如下所示。 在开发Android程序的时候,...2016-10-02
  • android.os.BinderProxy cannot be cast to com解决办法

    本文章来给大家介绍关于android.os.BinderProxy cannot be cast to com解决办法,希望此文章对各位有帮助呀。 Android在绑定服务的时候出现java.lang.ClassCastExc...2016-09-20
  • Android 实现钉钉自动打卡功能

    这篇文章主要介绍了Android 实现钉钉自动打卡功能的步骤,帮助大家更好的理解和学习使用Android,感兴趣的朋友可以了解下...2021-03-15
  • Android 开发之布局细节对比:RTL模式

    下面我们来看一篇关于Android 开发之布局细节对比:RTL模式 ,希望这篇文章对各位同学会带来帮助,具体的细节如下介绍。 前言 讲真,好久没写博客了,2016都过了一半了,赶紧...2016-10-02
  • swift中利用runtime交换方法的实现示例

    这篇文章主要给大家介绍了关于swift中利用runtime交换方法的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。...2020-06-30
  • Android中使用SDcard进行文件的读取方法

    首先如果要在程序中使用sdcard进行存储,我们必须要在AndroidManifset.xml文件进行下面的权限设置: 在AndroidManifest.xml中加入访问SDCard的权限如下: <!--...2016-09-20
  • Android开发之PhoneGap打包及错误解决办法

    下面来给各位简单的介绍一下关于Android开发之PhoneGap打包及错误解决办法,希望碰到此类问题的同学可进入参考一下哦。 在我安装、配置好PhoneGap项目的所有依赖...2016-09-20
  • 用Intel HAXM给Android模拟器Emulator加速

    Android 模拟器 Emulator 速度真心不给力,, 现在我们来介绍使用 Intel HAXM 技术为 Android 模拟器加速,使模拟器运行度与真机比肩。 周末试玩了一下在Eclipse中使...2016-09-20
  • 如何使用 JavaScript 操作浏览器历史记录 API

    这篇文章主要介绍了如何使用 JavaScript 操作浏览器历史记录 API,帮助大家更好的理解和使用JavaScript,感兴趣的朋友可以了解下...2020-11-24