You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Kotlin应用实时音频分贝显示延迟及-Infinity问题求助

问题解答

为什么会显示-Infinity?

核心原因是对数函数的输入为0:

  • 你代码里的分贝计算公式是20 * log10(recorder.maxAmplitude / 2700.0),当recorder.maxAmplitude返回0时,0 / 2700.0的结果是0,而数学上log10(0)的结果就是-Infinity。
  • maxAmplitude返回0的常见场景:MediaRecorder刚启动时还没采集到有效音频数据;另外,每次读取maxAmplitude后系统会自动将其重置为0,如果你的读取频率跟不上音频采集节奏,也会频繁读到0值。

关于实时更新延迟及是否需要Handler/Runnable

  1. 先排查当前timer的刷新间隔:如果你的timer是类似CountDownTimer这类工具,若间隔设置过大(比如1秒一次),必然导致UI更新延迟。建议把刷新间隔调整到100-200ms左右,平衡流畅度和性能消耗。
  2. 是否需要新的Handler/Runnable?
    • 如果当前timer的onTimeTick已经在主线程执行(比如CountDownTimer的onTick默认跑在主线程),额外加Handler/Runnable意义不大。从你直接操作binding控件的代码来看,当前onTimeTick应该已经在主线程。
    • 更推荐用Kotlin协程实现高频刷新,比Handler/Runnable更简洁易维护:
      lifecycleScope.launch {
          while (isRecording && !isPaused) {
              val amplitude = recorder.maxAmplitude
              // 处理振幅为0的情况,避免-Infinity
              val decibel = if (amplitude > 0) {
                  (20 * log10(amplitude / 2700.0)).toFloat()
              } else {
                  0f // 替换成你需要的默认显示值
              }
              binding.tvMaxDecibel.text = decibel.toString()
              binding.waveView.addAmplitude(amplitude.toFloat())
              delay(100) // 100ms刷新一次,可根据需求调整
          }
      }
      
  3. 额外优化点:
    • 读取maxAmplitude后必须做非零判断,提前规避对数计算的异常输入,避免显示-Infinity。
    • 避免在刷新回调里重复创建对象(比如你的代码里每次onTimeTick都处理日期?不,日期是在startRecording里处理的,这点没问题),尽量把固定逻辑移到初始化阶段。

内容的提问来源于stack exchange,提问作者Bruno

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 04:05:20