Как мне создать Media Player только один раз и вызывать его несколько раз? - PullRequest
0 голосов
/ 22 сентября 2019

Итак, я работаю над небольшой мобильной игрой, и когда я нажимаю на кнопку, она должна воспроизводить звуковой эффект.Я хочу, чтобы он воспроизводил несколько экземпляров за небольшой промежуток времени, поэтому SoundPool не работает в моем случае.Прямо сейчас я использую этот метод

public void playTapSound(){
        final MediaPlayer gameSound = MediaPlayer.create(this, R.raw.tapsound);
        gameSound.start();
    }

Однако я нигде не вызываю gameSound.release, так как не знаю, где его вызвать.Поэтому после 40 использований звуки перестают воспроизводиться, по-видимому, из-за слишком большого количества создаваемых MediaPlayer.

Я пытался поместить

final MediaPlayer gameSound = MediaPlayer.create(this, R.raw.tapsound);

в onCreate (), но когда я это делаю, gameSound становитсяошибка «Не удается разрешить символ« gameSound »».

Если поместить его до или после onCreate (), приложение просто вылетает, так как «this» равно нулю.

При нажатии кнопкиесть еще кое-что, тогда я тоже запускаю

    public void tapped(View view) {
        if (!buttons[0].isAllCaps()) {
            playTapSound();
            buttons[0].setBackgroundColor(Color.parseColor("#1fab89"));
            buttons[0].setAllCaps(true);
            score++;
            x++;
            points.setText(String.valueOf(score));
        }
        else {
            buttons[0].setBackgroundColor(Color.parseColor("#505bda"));
            lose(score);
        }
    }

Надеюсь, я могу получить некоторую помощь о том, где разместить gameSound.release () или как вызвать gameSound, когда игрок создается на onCreate ().спасибо

Ответы [ 2 ]

0 голосов
/ 22 сентября 2019

gameSound становится локальной переменной в обеих ваших попытках.Во-первых, он локальный для playTapSound() и, следовательно, недоступен из других источников, во-вторых, он локальный для onCreate() и, следовательно, даже недоступен из playTapSound().
Вместо этого создайте переменную уровня объекта внеметоды (и, следовательно, доступные для всех):

private MediaPlayer gameSound;

... onCreate(){
  ...
  gameSound=MediaPlayer.create(this,R.raw.tapsound);
  ...
}

public void playTapSound(){
  gameSound.start();
}

(Однако я не знаю, будет ли он работать, это предложение фокусируется на проблеме компиляции + видимости, я не знаю, если start()может вызываться несколько раз - возможно, да, возможно, вы можете просто поставить остановку непосредственно перед стартом, возможно, вам придется отслеживать, продолжает ли она играть, и останавливать ее только в этом случае).

(примечание стороны: final делает переменную неизменяемой после инициализации. Она не связана с разделением переменных между методами, и здесь она вам не нужна.)

0 голосов
/ 22 сентября 2019

Как насчет использования Синглтон ?

public final class MediaPlayerHolder {
    private static final MediaPlayerHolder INSTANCE = new MediaPlayerHolder();

    public static MediaPlayerHolder getInstance() {
        return INSTANCE;
    }

    private MediaPlayerHolder() {
    }


    private MediaPlayer gameSound;

    // get with required parameters
    public MediaPlayer get(...) {
        if(mediaPlayer == null)
            gameSound = MediaPlayer.create(...);
        return gameSound;
    }

}

public void playTapSound(){
    MediaPlayerHolder.getInstance().get().start();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...