perf(android): батарея и плавность — gate FFT, изоляция рекомпозиции, поллинг на паузе

- AudioSpectrumAnalyzer: FFT считается ТОЛЬКО когда открыт плеер (флаг active);
  раньше ~86 FFT/с молотили всегда при проигрывании (даже экран выкл) — главный
  пожиратель батареи. Включается из VisualizerHost через DisposableEffect.
- Спектр (45/с) собирается в leaf VisualizerHost, а не на верху PlayerBottomSheet —
  весь плеер больше не рекомпозится 45 раз/сек.
- now-playing поллинг (5с) останавливается на паузе (isPlaying.collectLatest) —
  раньше на паузе зря дёргали сеть каждые 5с.
- PlayerService.onDestroy отменяет serviceScope (singleton-плеер НЕ релизим).
- refreshStations (парс ~700 станций + сеть + Room) уведён на Dispatchers.IO с
  главного потока (jank/ANR на старте).
- Coil ImageLoader: память 25% + диск 100МБ (обложки не перекачиваются каждую сессию).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
nk
2026-06-06 16:33:00 +03:00
parent 861b0e2b8f
commit f423344d13
7 changed files with 97 additions and 12 deletions

View File

@@ -28,6 +28,7 @@ import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancel
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
@@ -346,6 +347,11 @@ class PlayerController @Inject constructor(
_sleepRemainingMs.value = null
}
/** Включить/выключить расчёт спектра (FFT) — только пока открыт плеер. */
fun setSpectrumActive(active: Boolean) {
spectrumAnalyzer.active = active
}
fun pause() {
exoPlayer.pause()
}
@@ -361,6 +367,7 @@ class PlayerController @Inject constructor(
}
fun release() {
timerScope.cancel()
audioManager.unregisterAudioDeviceCallback(audioDeviceCallback)
sleepSoundPlayer.stop()
exoPlayer.release()