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 确保时间逻辑的准确性。

相关推荐
雨白14 分钟前
开发 SunnyWeather:Android 天气预报 App(下)
android
_extraordinary_2 小时前
Java 字符串常量池 +反射,枚举和lambda表达式
android·java·开发语言
alexhilton2 小时前
学会说不!让你彻底学会Kotlin Flow的取消机制
android·kotlin·android jetpack
来来走走2 小时前
Flutter dart运算符
android·前端·flutter
青小莫2 小时前
IDM下载失败常见原因
android
阿华的代码王国3 小时前
【Android】日期选择器
android·xml·java·前端·后端
小墙程序员5 小时前
Android 性能优化(五)Heap Dump 的使用
android·性能优化
阿华的代码王国5 小时前
【Android】RecyclerView实现新闻列表布局(1)适配器使用相关问题
android·xml·java·前端·后端
EngZegNgi5 小时前
Unity —— Android 应用构建与发布
android·unity·自动化·游戏引擎·构建
fatiaozhang95275 小时前
烽火HG680-KX-海思MV320芯片-2+8G-安卓9.0-强刷卡刷固件包
android·电视盒子·刷机固件·机顶盒刷机