System.currentTimeMillis()与elapsedRealtime()区别

System.currentTimeMillis()SystemClock.elapsedRealtime() 在 Android 开发中用于不同的时间测量场景,核心区别在于它们的底层实现和对系统时间变化的敏感度。以下是详细说明和代码示例:


1. System.currentTimeMillis()

  • 定义:返回自 1970 年 1 月 1 日 UTC 以来的毫秒数(Unix 时间戳)。
  • 特点
    • 受系统时间设置影响(用户或网络时间同步可能导致时间跳变)。
    • 设备休眠时不会递增。
  • 适用场景:需要与真实时间相关的操作,如记录事件时间、生成日期字符串等。

代码示例:记录事件时间戳

java 复制代码
// 记录用户点击事件的时间
long clickTime = System.currentTimeMillis();
saveToDatabase("User clicked at " + clickTime);

// 将时间戳转换为可读日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
String dateStr = sdf.format(new Date(clickTime));
Log.d("EventTime", "点击时间: " + dateStr);

2. SystemClock.elapsedRealtime()

  • 定义:返回自设备启动以来经过的毫秒数(包括深度休眠时间)。
  • 特点
    • 不受系统时间设置影响。
    • 设备休眠时仍会累计时间。
  • 适用场景:测量时间间隔(如性能统计、倒计时),需稳定不受系统时间干扰的场景。

代码示例:测量代码执行时间

java 复制代码
// 开始计时
long startTime = SystemClock.elapsedRealtime();

// 模拟耗时操作(如下载文件)
new Thread(() -> {
    try {
        Thread.sleep(2000); // 模拟 2 秒操作
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    // 计算实际耗时
    long endTime = SystemClock.elapsedRealtime();
    long duration = endTime - startTime;
    Log.d("Performance", "操作耗时: " + duration + " 毫秒");
}).start();

错误用法示例

错误:使用 System.currentTimeMillis() 计算耗时

java 复制代码
long start = System.currentTimeMillis();
// 假设用户在此期间调整了系统时间
Thread.sleep(5000); // 实际耗时 5 秒
long end = System.currentTimeMillis();
long wrongDuration = end - start; // 可能得到负数或极大值

正确:使用 SystemClock.elapsedRealtime()

java 复制代码
long start = SystemClock.elapsedRealtime();
Thread.sleep(5000);
long end = SystemClock.elapsedRealtime();
long correctDuration = end - start; // 始终准确为 ~5000 毫秒

总结对比表

特性 System.currentTimeMillis() SystemClock.elapsedRealtime()
时间基准 Unix 时间戳(1970 年) 设备启动后经过的时间
系统时间敏感 ✔️(用户修改时间会影响结果) ❌(结果稳定,不受时间设置影响)
休眠时递增 ❌(休眠时暂停) ✔️(持续计时,包括休眠)
典型用途 日历事件、日志时间戳 性能统计、倒计时、间隔测量

高级场景:跨进程时间同步

在需要跨组件(如 ServiceActivity)同步时间的场景中,elapsedRealtime() 更可靠。例如,音乐播放器显示播放进度:

java 复制代码
// Service 中记录播放开始时间
long playbackStartTime = SystemClock.elapsedRealtime();

// Activity 中实时计算已播放时长
long currentElapsed = SystemClock.elapsedRealtime();
long playbackDuration = currentElapsed - playbackStartTime;
updateUI("已播放: " + playbackDuration + " 毫秒");

通过理解两者的差异,可以在不同场景中选择合适的 API 确保时间逻辑的准确性。

相关推荐
恋猫de小郭1 小时前
再次紧急修复,Flutter 针对 WebView 无法点击问题增加新的快速修复
android·前端·flutter
李慕婉学姐1 小时前
【开题答辩过程】以《基于Android的健康助手APP的设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
android·java·mysql
似霰3 小时前
传统 Hal 开发笔记6----App 访问硬件服务
android·framework·hal
爱装代码的小瓶子4 小时前
【c++知识铺子】封装map和set(详细版)
android·java·c++
私人珍藏库4 小时前
AutoGLM无需豆包手机,让AI自动帮你点外卖-刷视频
android·ai·智能手机·工具·软件·辅助·autoglm
孤舟簔笠翁5 小时前
【Android驱动14】Android系统Crash工具使用方法和分析
android
帅得不敢出门6 小时前
MTK Android11 APP调用OTA升级
android·java·开发语言·framework
2501_915909066 小时前
苹果应用加密方案的一种方法,在没有源码的前提下,如何处理 IPA 的安全问题
android·安全·ios·小程序·uni-app·iphone·webview
用户2018792831676 小时前
Android App 换肤原理:用 "装修小房子" 故事浅谈
android