Несколько проигрывателей MediaPlayer не работают - Android studio

Я новичок в разработке Android и Java, и мне нужны рекомендации по настройке простого приложения для деки. То, что я пытаюсь сделать и у меня возникают проблемы с его эффективной работой, - это обработка событий для нескольких медиаплееров.

Например, я создаю деку, посредством которой, когда я нажимаю кнопку, я хочу, чтобы все остальные звуки были остановлены и высвобождены из памяти, и кнопку, которую я только что нажал, для воспроизведения назначенного звука. Я понимаю, что повторение блоков кода - не лучший подход к программированию, но я пробовал это с массивами и операторами переключения, но без особого эффекта. Мне были бы очень полезны любые инструкции по эффективному освобождению звуков из памяти при использовании нескольких MediaPlayers. Я добавил свой код ниже для 4 кнопок (в этом приложении у меня их более 30)

public class MainActivity extends AppCompatActivity {


private MediaPlayer Meow1,Meow2,Meow3,Meow4;
private Button meowButton1,meowButton2,meowButton3,meowButton4;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);



 Meow1 = new MediaPlayer();
        Meow1 = MediaPlayer.create(getApplicationContext(), R.raw.meow1);
       // final Boolean Meow1Pause = !Meow1.isPlaying() && Meow1.getCurrentPosition() >1;
        meowButton1 = (Button) findViewById(R.id.Meow1);
        meowButton1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (Meow1.isPlaying())
                { pauseMusic1();
                } else {
                    Meow1.start();
                }}
        });
        Meow1.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer Meow1) {
                Meow1.stop();
                Meow1.reset();
                Meow1.release();

            }
        });



       Meow2 = new MediaPlayer();
       Meow2 = MediaPlayer.create(getApplicationContext(), R.raw.meow2);

        meowButton2 = (Button) findViewById(R.id.Meow2);
        meowButton2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (Meow2.isPlaying() ){
                    pauseMusic();
                } else {
                    Meow2.start();      
        }}
        });

        Meow2.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer Meow1) {
                Meow2.stop();
                Meow2.reset();
                Meow2.release();
            }
        });

        Meow3 = new MediaPlayer();
        Meow3 = MediaPlayer.create(getApplicationContext(), R.raw.meow3);
        meowButton3 = (Button) findViewById(R.id.Meow3);
        meowButton3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (Meow3.isPlaying())
                { pauseMusic();
                } else {
                    Meow3.start();
                }}
        });
        Meow3.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer Meow1) {
                Meow3.stop();
                Meow3.reset();
                Meow3.release();

            }
        });

        Meow4 = new MediaPlayer();
        Meow4  = MediaPlayer.create(getApplicationContext(), R.raw.meow4);
        meowButton4 = (Button) findViewById(R.id.Meow4);
        meowButton4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (Meow4.isPlaying())
                { pauseMusic();
                } else {
                    Meow4.start();
                }}
        });

}
public void pauseMusic()  {
    if (Meow1 != null && Meow1.isPlaying()) Meow1.pause();
    if (Meow2 != null && Meow2.isPlaying()) Meow2.pause();
    if (Meow3 != null && Meow3.isPlaying()) Meow3.pause();
    if (Meow4 != null && Meow4.isPlaying()) Meow4.pause();
}


}

Run Compiler:
A: Logging event (FE): screen_view(_vs), Bundle[{firebase_event_origin(_o)=auto, firebase_previous_class(_pc)=SplashScreen, firebase_previous_id(_pi)=-6549553702477848745, firebase_screen_class(_sc)=MainActivity, firebase_screen_id(_si)=-6549553702477848744}]
I/zygote: Do partial code cache collection, code=124KB, data=67KB
I/zygote: After code cache collection, code=124KB, data=67KB
I/zygote: Increasing code cache capacity to 512KB
V/FA: Activity resumed, time: 6376787
D/EGL_emulation: eglMakeCurrent: 0x980fde60: ver 3 0 (tinfo 0xa3c3c290)
D/EGL_emulation: eglMakeCurrent: 0x980fde60: ver 3 0 (tinfo 0xa3c3c290)
D/EGL_emulation: eglMakeCurrent: 0x980fde60: ver 3 0 (tinfo 0xa3c3c290)
I/chatty: uid=10085(u0_a85) RenderThread identical 2 lines
D/EGL_emulation: eglMakeCurrent: 0x980fde60: ver 3 0 (tinfo 0xa3c3c290)
V/FA: Inactivity, disconnecting from the service
V/MediaPlayer: resetDrmState:  mDrmInfo=null mDrmProvisioningThread=null mPrepareDrmInProgress=false mActiveDrmScheme=false
               cleanDrmObj: mDrmObj=null mDrmSessionId=null
V/MediaPlayer: resetDrmState:  mDrmInfo=null mDrmProvisioningThread=null mPrepareDrmInProgress=false mActiveDrmScheme=false
               cleanDrmObj: mDrmObj=null mDrmSessionId=null
D/TAG1: Button 2 pressed
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: g.convery.cat_sounds, PID: 12276
                  java.lang.IllegalStateException
                      at android.media.MediaPlayer.isPlaying(Native Method)
                      at g.convery.cat_sounds.MainActivity$1.onClick(MainActivity.java:97)
                      at android.view.View.performClick(View.java:6256)
                      at android.view.View$PerformClick.run(View.java:24701)
                      at android.os.Handler.handleCallback(Handler.java:789)
                      at android.os.Handler.dispatchMessage(Handler.java:98)
                      at android.os.Looper.loop(Looper.java:164)
                      at android.app.ActivityThread.main(ActivityThread.java:6541)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
W/MediaPlayer-JNI: MediaPlayer finalized without being released
W/MediaPlayer-JNI: MediaPlayer finalized without being released
Application terminated.


LOGCAT:

05-31 09:21:30.099 12276-12288/g.convery.cat_sounds W/MediaPlayer-JNI: MediaPlayer finalized without being released
05-31 09:21:30.211 12276-12288/g.convery.cat_sounds I/chatty: uid=10085(u0_a85) FinalizerDaemon identical 33 lines
05-31 09:21:30.212 12276-12288/g.convery.cat_sounds W/MediaPlayer-JNI: MediaPlayer finalized without being released
05-31 09:21:30.283 12276-12284/g.convery.cat_sounds I/zygote: Do partial code cache collection, code=124KB, data=67KB
05-31 09:21:30.286 12276-12284/g.convery.cat_sounds I/zygote: After code cache collection, code=124KB, data=67KB
05-31 09:21:30.287 12276-12284/g.convery.cat_sounds I/zygote: Increasing code cache capacity to 512KB
05-31 09:21:31.159 12276-12307/g.convery.cat_sounds I/chatty: uid=10085(u0_a85) RenderThread identical 2 lines
05-31 09:24:41.746 12276-12276/g.convery.cat_sounds E/AndroidRuntime: FATAL EXCEPTION: main
    Process: g.convery.cat_sounds, PID: 12276
    java.lang.IllegalStateException
        at android.media.MediaPlayer.isPlaying(Native Method)
        at g.convery.cat_sounds.MainActivity$1.onClick(MainActivity.java:97)
        at android.view.View.performClick(View.java:6256)
        at android.view.View$PerformClick.run(View.java:24701)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6541)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
05-31 09:24:47.955 12276-12288/g.convery.cat_sounds W/MediaPlayer-JNI: MediaPlayer finalized without being released
05-31 09:24:47.956 12276-12288/g.convery.cat_sounds W/MediaPlayer-JNI: MediaPlayer finalized without being released
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
361
2

Ответы 2

Вы используете медиаплеер после его выпуска. Удалите эти строки из своего onCompletionListener и вместо этого добавьте их в onDestroy своей активности.

Meow1.release();
Meow2.release();
Meow3.release();
Meow4.release();

Также вызов create автоматически создает новый экземпляр, вы также можете удалить эти строки

Meow1 = new MediaPlayer();
Meow2 = new MediaPlayer();
Meow3 = new MediaPlayer();
Meow4 = new MediaPlayer();

Лучшим подходом было бы использовать один медиаплеер и просто изменить источник даты, когда пользователь захочет воспроизвести другой источник, но этот метод займет некоторое время, прежде чем он воспроизведет звук, поскольку он будет готовить звук каждый раз, это было бы незначительным, если только ваш аудио размер довольно велик

  1. Посмотрите, как вы сейчас контролируете свои медиа:

    if (Meow4.isPlaying()) { 
        pauseMusic();
    } else {
        Meow4.start();
    }
    

    При первом вызове Meow4.isPlaying() вы получите IllegalStateException, потому что ваш проигрыватель не инициализирован.

    Посмотрите, как определяется ваше состояние MediaPlayer, и вызовите соответствующую функцию

  2. Второй момент: когда вы сталкиваетесь с повторяющимся блоком, вам следует подумать о функции.

    Meow3 = new MediaPlayer();
    Meow3 = MediaPlayer.create(getApplicationContext(), R.raw.meow3);
    meowButton3 = (Button) findViewById(R.id.Meow3);
    meowButton3.setOnClickListener(new View.OnClickListener() {
    
    });
    meowButton3.setOnCompletionListener...
    

в функции: registerPlayer(Context context, int resourceId, Button controlButton)

Or with higher level of abstraction, create a subclass of `MediaPlayer` and wrap these logic inside it
  1. Определенно, вы не хотите повторять Meow1.pause() снова и снова. Вместо этого сохраните ваш MeoX в списке, а затем переберите его:

    List<MediaPlayer> players = new ArrayList<>();
    players.add(Meow1);
    ....
    public void pauseMusic()  {
         players.stream().filter(p -> p != null && p.isPlaying()).forEach(p -p.pause());
    }
    

Спасибо друг. Я отказался от класса MediaPlayer в пользу класса SoundPool, который кажется лучшим способом создания приложения для звуковой платы. Спасибо за вашу помощь, я буду использовать это решение для своего следующего приложения. Я открыл еще один пост, посвященный некоторым проблемам, с которыми я сейчас сталкиваюсь в классе SoundPool. stackoverflow.com/questions/50635392/…

Sean Power 01.06.2018 06:03

Другие вопросы по теме