Короткие звуки — важная деталь, которая делает приложение отзывчивым: щелчок кнопки, сигнал оповещения или звук завершения операции. Воспроизводить такие аудиофрагменты через MediaPlayer неудобно: он рассчитан на длинные треки, долго готовится и занимает много ресурсов. Поэтому в Android существует более легковесный инструмент — SoundPool. Сегодня в Android Studio мы разберём его на практике и напишем небольшое приложение на Kotlin, которое будет озвучивать действия пользователя. Этот урок поможет добавить в проект быстрые и экономичные звуковые эффекты.
SoundPool против MediaPlayer: что выбрать
MediaPlayer подходит для фоновой музыки и длинных аудиозаписей: он умеет управлять состоянием, буферизировать поток и работать с сетью. Но если нужно воспроизвести десять коротких щелчков в секунду, MediaPlayer будет «захлёбываться» и расходовать лишнюю память. SoundPool решает эту задачу: он заранее загружает звук в оперативную память и проигрывает его почти мгновенно, практически без задержки. Ограничение — размер файла: обычно не больше 1 мегабайта, иначе могут быть проблемы на старых устройствах.
Подготовка звуковых файлов
Поместите короткие аудиофайлы в папку res/raw вашего проекта. Если такой папки ещё нет, создайте её. Для демонстрации подойдут любые звуки в формате MP3, OGG или WAV. Назовём их, например, click.mp3 и done.mp3. Обращаться к ним будем по идентификаторам R.raw.click и R.raw.done. Никаких дополнительных разрешений в манифесте не нужно, потому что файлы встроены в приложение.
Создаём SoundPool и загружаем звуки
В MainActivity.kt объявим переменные для SoundPool и идентификаторов загруженных звуков. Инициализацию выполним в onCreate. Конструктор SoundPool принимает максимальное количество одновременно проигрываемых потоков (обычно хватает 4–5), тип потока (например, AudioManager.STREAM_MUSIC) и качество (оставьте 0). Затем вызовем load() для каждого файла — он вернёт целочисленный ID, который пригодится для воспроизведения.
class MainActivity : AppCompatActivity() {
private var soundPool: SoundPool? = null
private var clickSoundId = 0
private var doneSoundId = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
soundPool = SoundPool.Builder()
.setMaxStreams(4)
.build()
clickSoundId = soundPool?.load(this, R.raw.click, 1) ?: 0
doneSoundId = soundPool?.load(this, R.raw.done, 1) ?: 0
}
}
Третий параметр метода load() — приоритет, сейчас он не используется, но должен быть равен 1.
Воспроизведение звука по нажатию
Разместим в разметке две кнопки. При нажатии на каждую будем воспроизводить соответствующий звук с помощью метода play(). Он принимает ID загруженного звука, громкость для левого и правого каналов (от 0.0 до 1.0), приоритет (0), режим повтора (0 — без повтора, -1 — бесконечно) и скорость (1.0 — нормальная).
btnClick.setOnClickListener {
soundPool?.play(clickSoundId, 1.0f, 1.0f, 0, 0, 1.0f)
}
btnDone.setOnClickListener {
soundPool?.play(doneSoundId, 1.0f, 1.0f, 0, 0, 1.0f)
}
Звук воспроизведётся немедленно, без ощутимой задержки. Если нажать кнопку много раз подряд, SoundPool будет накладывать звуки друг на друга, не обрывая предыдущие.
Освобождение ресурсов
SoundPool, как и любой системный объект, нужно освобождать, когда он больше не нужен. Лучшее место для этого — метод onDestroy(). Вызов release() очищает память и освобождает аудиоресурсы.
override fun onDestroy() {
super.onDestroy()
soundPool?.release()
soundPool = null
}
Полезные советы
- Формат OGG предпочтительнее. Он даёт хорошее сжатие без потери качества и корректно работает на всех устройствах. MP3 иногда вызывает задержки при первом воспроизведении.
- Не загружайте большие файлы. SoundPool держит данные в оперативной памяти. Файлы больше мегабайта могут не загрузиться на старых телефонах.
- Обрабатывайте ошибку загрузки. Метод
load()возвращает 0, если файл не найден. Проверяйте это значение перед вызовомplay(). - Используйте AudioAttributes для современных API. Вместо устаревшего
AudioManager.STREAM_MUSICзадайте атрибуты черезAudioAttributes.Builder()и передайте их вSoundPool.Builder().setAudioAttributes().
Коротко о главном
Этот урок в Android Studio на Kotlin показал, как легко добавить в приложение звуковые эффекты через SoundPool. Вы загрузили короткие аудиофайлы, воспроизвели их по нажатию кнопок и не забыли освободить ресурсы. Теперь ваши приложения могут звучать живо и отзывчиво, не расходуя лишнюю память. Попробуйте добавить разные звуки на разные действия — это сразу улучшит восприятие интерфейса.