Zarządzanie stanem i zasobami MediaPlayer

W tym dokumencie omawiamy 2 obszary, w których mogą wystąpić problemy.

  • Stan W przypadku „Medialayer” niektóre operacje są prawidłowe tylko w określonych stanach. Nieprawidłowe operacje mogą powodować wyjątki lub nieoczekiwane działanie.

  • Zasoby Gdy wprowadzasz zmiany w konfiguracji, np. obracasz ekran, musisz zwolnić obiekt MediaPlayer, aby zwolnić zasoby systemowe i uniknąć ich wyczerpania.

Zarządzanie stanem

MediaPlayer jest oparta na stanie. Oznacza to, że ma on stan wewnętrzny, o którym musisz zawsze pamiętać podczas pisania kodu, ponieważ niektóre operacje są prawidłowe tylko wtedy, gdy odtwarzacz jest w określonym stanie. Jeśli wykonasz operację w niewłaściwym stanie, system może zgłosić wyjątek lub spowodować inne niepożądane zachowania.

Diagram stanu w dokumentacji klasy MediaPlayer wyjaśnia, które metody przenoszą MediaPlayer z jednego stanu do drugiego. Przykład:

  • Gdy utworzysz nowy MediaPlayer, będzie on w stanie Idle (Bezczynny).
  • Inicjujesz go, wywołując setDataSource(), co zmienia jego stan na Initialized.
  • Przygotowujesz go za pomocą metody prepare() lub prepareAsync().
  • Gdy MediaPlayer zakończy przygotowywanie, przechodzi w stan Prepared, co oznacza, że możesz wywołać start(), aby odtworzyć multimedia.

W tym momencie, jak pokazuje diagram, możesz przełączać się między stanami Started, PausedPlaybackCompleted, wywołując m.in. metody start(), pause()seekTo().

Jeśli jednak zadzwonisz pod numer stop(), nie będziesz mieć możliwości ponownego zadzwonienia pod numer start(), dopóki nie przygotujesz ponownie MediaPlayer.

Podczas pisania kodu, który wchodzi w interakcję z obiektem MediaPlayer, zawsze pamiętaj o diagramie stanu, ponieważ wywoływanie jego metod w niewłaściwym stanie jest częstą przyczyną błędów.

Zwalnianie odtwarzacza MediaPlayer

MediaPlayer może zużywać cenne zasoby systemowe. Dlatego zawsze zachowuj szczególną ostrożność, aby nie przechowywać instancji MediaPlayer dłużej niż to konieczne. Po zakończeniu pracy z nią zawsze wywołuj funkcję release(), aby mieć pewność, że wszystkie zasoby systemowe przydzielone do niej zostaną prawidłowo zwolnione.

Jeśli na przykład używasz MediaPlayer, a Twoja aktywność odbiera wywołanie onStop(), musisz zwolnić MediaPlayer, ponieważ nie ma sensu go przechowywać, gdy Twoja aktywność nie wchodzi w interakcję z użytkownikiem (chyba że odtwarzasz multimedia w tle, co omówiono w następnej sekcji).

Gdy aktywność zostanie wznowiona lub ponownie uruchomiona, musisz utworzyć nowy MediaPlayer i przygotować go ponownie przed wznowieniem odtwarzania.

Aby zwolnić, a potem unieważnić MediaPlayer:

Kotlin

mediaPlayer?.release()
mediaPlayer = null

Java

mediaPlayer.release();
mediaPlayer = null;

Rozważmy na przykład problemy, które pojawią się, jeśli zapomnisz zwolnić MediaPlayer po zakończeniu aktywności, ale utworzysz nowe, gdy aktywność się ponownie rozpocznie. Gdy użytkownik zmieni orientację ekranu (lub w inny sposób zmieni konfigurację urządzenia), system domyślnie ponownie uruchomi aktywność. Możesz szybko wyczerpać wszystkie zasoby systemowe, gdy użytkownik będzie obracać urządzenie między orientacją pionową i poziomą, ponieważ przy każdej zmianie orientacji tworzysz nowy obiekt MediaPlayer, którego nigdy nie zwalniasz.

Więcej informacji o ponownym uruchamianiu środowiska wykonawczego znajdziesz w artykule Obsługa zmian w środowisku wykonawczym.

Możesz się zastanawiać, co się stanie, jeśli chcesz kontynuować odtwarzanie „multimediów w tle”, nawet gdy użytkownik opuści Twoją aktywność, podobnie jak w przypadku wbudowanej aplikacji Muzyka. W takim przypadku potrzebujesz elementu MediaPlayer kontrolowanego przez usługę, o czym piszemy w następnej sekcji.

Więcej informacji

Jetpack Media3 to zalecane rozwiązanie do odtwarzania multimediów w aplikacji. Więcej informacji

Na tych stronach znajdziesz informacje o nagrywaniu, przechowywaniu i odtwarzaniu dźwięku i obrazu: