MediaPlayer 상태 및 리소스 관리
컬렉션을 사용해 정리하기
내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요.
이 문서에서는 잠재적인 함정이 있는 두 가지 영역을 다룹니다.
상태 관리
MediaPlayer
는 상태 기반입니다. 즉, 에는 코드를 작성할 때 항상 알고 있어야 하는 내부 상태가 있습니다. 특정 작업은 플레이어가 특정 상태에 있을 때만 유효하기 때문입니다. 잘못된 상태에서 작업을 실행하면 시스템에서 예외나 다른 바람직하지 않은 동작이 발생할 수 있습니다.
MediaPlayer
클래스 문서의 상태 다이어그램은 어떤 메서드가 MediaPlayer
를 한 상태에서 다른 상태로 이동하는지 명확히 보여줍니다. 예를 들면 다음과 같습니다.
이 시점에서 다이어그램과 같이 start()
, pause()
, seekTo()
와 같은 메서드를 호출하여 Started
, Paused
, PlaybackCompleted
상태 사이를 이동할 수 있습니다.
그러나 stop()
를 호출하면 MediaPlayer
를 다시 준비할 때까지 start()
를 다시 호출할 수 없습니다.
MediaPlayer
객체와 상호작용하는 코드를 작성할 때는 항상 상태 다이어그램을 기억하세요. 잘못된 상태에서 메서드를 호출하는 것이 버그가 발생하는 일반적인 원인이기 때문입니다.
MediaPlayer 해제
MediaPlayer
는 귀중한 시스템 리소스를 소비할 수 있습니다. 따라서 항상 특히 주의를 기울여 필요 이상으로 오래 MediaPlayer
인스턴스를 유지하지 않는지 확인해야 합니다. 작업이 끝나면 항상 release()
를 호출하여 할당된 시스템 리소스가 올바르게 해제되었는지 확인해야 합니다.
예를 들어 MediaPlayer
를 사용 중이고 활동이 onStop()
호출을 수신하는 경우 MediaPlayer
를 해제해야 합니다. 활동이 사용자와 상호작용하지 않는 동안 MediaPlayer
를 유지하는 것은 거의 의미가 없기 때문입니다 (다음 섹션에서 설명하는 백그라운드에서 미디어를 재생하는 경우는 예외).
물론 활동이 재개되거나 다시 시작되면 새로운 MediaPlayer
를 만들고 준비한 후 재생을 다시 시작해야 합니다.
다음은 MediaPlayer
를 해제한 다음 무효화하는 방법입니다.
Kotlin
mediaPlayer?.release()
mediaPlayer = null
자바
mediaPlayer.release();
mediaPlayer = null;
예를 들어 활동이 중지될 때 MediaPlayer
를 해제하지 않고 활동이 다시 시작될 때 새 MediaPlayer를 만든 경우 발생할 수 있는 문제를 생각해 보세요. 사용자가 화면 방향을 변경하거나 다른 방식으로 기기 구성을 변경하면 시스템은 기본적으로 활동을 다시 시작합니다. 사용자가 기기를 세로 모드와 가로 모드 간에 앞뒤로 회전할 때 모든 시스템 리소스가 빠르게 소모될 수 있습니다. 방향이 변경될 때마다 해제하지 않는 새 MediaPlayer
를 만들기 때문입니다.
런타임 다시 시작에 관한 자세한 내용은 런타임 변경 처리를 참고하세요.
사용자가 활동을 떠날 때에도 내장된 음악 애플리케이션이 동작하는 것과 동일한 방식으로 '백그라운드 미디어'를 계속 재생하려는 경우 어떤 일이 발생하는지 궁금할 수 있습니다. 이 경우 필요한 것은 서비스에서 제어하는 MediaPlayer
입니다. 다음 섹션에서 설명합니다.
자세히 알아보기
Jetpack Media3는 앱에서 미디어를 재생하는 데 권장되는 솔루션입니다. 자세한 내용은 자세히 알아보세요.
이 페이지에서는 오디오와 동영상 녹음/녹화, 저장 및 재생과 관련된 주제를 다룹니다.
이 페이지에 나와 있는 콘텐츠와 코드 샘플에는 콘텐츠 라이선스에서 설명하는 라이선스가 적용됩니다. 자바 및 OpenJDK는 Oracle 및 Oracle 계열사의 상표 또는 등록 상표입니다.
최종 업데이트: 2025-07-27(UTC)
[[["이해하기 쉬움","easyToUnderstand","thumb-up"],["문제가 해결됨","solvedMyProblem","thumb-up"],["기타","otherUp","thumb-up"]],[["필요한 정보가 없음","missingTheInformationINeed","thumb-down"],["너무 복잡함/단계 수가 너무 많음","tooComplicatedTooManySteps","thumb-down"],["오래됨","outOfDate","thumb-down"],["번역 문제","translationIssue","thumb-down"],["샘플/코드 문제","samplesCodeIssue","thumb-down"],["기타","otherDown","thumb-down"]],["최종 업데이트: 2025-07-27(UTC)"],[],[],null,["# Manage MediaPlayer state and resources\n\nThis document covers two areas with potential pitfalls.\n\n- **State.** With \"Medialayer\\`, certain operations are valid only in specific\n states. Incorrect operations can cause exceptions or unexpected behavior.\n\n- **Resources** When you make configuration changes, such as screen rotation,\n You must release a `MediaPlayer` object to free up system resources and\n avoid resource exhaustion.\n\nManage state\n------------\n\n[`MediaPlayer`](/reference/android/media/MediaPlayer) is state-based. That is, it has an\ninternal state that you must\nalways be aware of when you write your code, because certain operations are only\nvalid when the player is in specific states. If you perform an operation while\nin the wrong state, the system may throw an exception or cause other undesirable\nbehaviors.\n\nThe state diagram in the [`MediaPlayer`](/reference/android/media/MediaPlayer) class documentation clarifies\nwhich methods move the [`MediaPlayer`](/reference/android/media/MediaPlayer) from one state\nto another. For example:\n\n- When you create a new [`MediaPlayer`](/reference/android/media/MediaPlayer), it is in the *Idle* state.\n- You initialize it by calling[`setDataSource()`](/reference/android/media/MediaPlayer#setDataSource(android.content.Context,%20android.net.Uri)), which changes it to the *Initialized* state.\n- You prepare it using either the [`prepare()`](/reference/android/media/MediaPlayer#prepare()) or [`prepareAsync()`](/reference/android/media/MediaPlayer#prepareAsync()) method.\n- When the [`MediaPlayer`](/reference/android/media/MediaPlayer) is done preparing, it enters the `Prepared` state, which means you can call [`start()`](/reference/android/media/MediaPlayer#start()) to make it play the media.\n\nAt that point, as the diagram illustrates, you can move between the `Started`,\n`Paused` and `PlaybackCompleted` states by calling such methods as\n[`start()`](/reference/android/media/MediaPlayer#start()), [`pause()`](/reference/android/media/MediaPlayer#pause()), and [`seekTo()`](/reference/android/media/MediaPlayer#seekTo(int)), among others.\n\nWhen you call [`stop()`](/reference/android/media/MediaPlayer#stop()), however, notice that you cannot call [`start()`](/reference/android/media/MediaPlayer#start())\nagain until you prepare the [`MediaPlayer`](/reference/android/media/MediaPlayer) again.\n\nAlways keep [the state diagram](/static/images/mediaplayer_state_diagram.gif) in mind when writing code that interacts with\na [`MediaPlayer`](/reference/android/media/MediaPlayer) object, because calling its methods from the wrong state is\na common cause of bugs.\n\nRelease the MediaPlayer\n-----------------------\n\nA [`MediaPlayer`](/reference/android/media/MediaPlayer) can consume valuable system resources. Therefore, you\nshould always take extra precautions to make sure you are not hanging on to a\n[`MediaPlayer`](/reference/android/media/MediaPlayer) instance longer than necessary. When you are done with it,\nyou should always call [`release()`](/reference/android/media/MediaPlayer#release()) to make sure any system resources\nallocated to it are properly released.\n\nFor example, if you are using a [`MediaPlayer`](/reference/android/media/MediaPlayer) and your activity receives a\ncall to [`onStop()`](/reference/android/app/Activity#onStop()), you must release the [`MediaPlayer`](/reference/android/media/MediaPlayer), because it\nmakes little sense to hold on to it while your activity is not interacting with\nthe user (unless you are playing media in the background, which is discussed in\nthe next section).\n\nWhen your activity is resumed or restarted, of course, you need to create a new\n[`MediaPlayer`](/reference/android/media/MediaPlayer) and prepare it again before resuming playback.\n\nHere's how you should release and then nullify your [`MediaPlayer`](/reference/android/media/MediaPlayer): \n\n### Kotlin\n\n mediaPlayer?.release()\n mediaPlayer = null\n\n### Java\n\n mediaPlayer.release();\n mediaPlayer = null;\n\nAs an example, consider the problems that arise if you forget to release the\n[`MediaPlayer`](/reference/android/media/MediaPlayer) when your activity stops, but create a new one when the\nactivity starts again. When the user changes the screen orientation (or changes\nthe device configuration in another way), the system restarts the activity by\ndefault. You might quickly consume all of the system resources as the user\nrotates the device back and forth between portrait and landscape, because at\neach orientation change, you create a new [`MediaPlayer`](/reference/android/media/MediaPlayer) that you never\nrelease.\n\nFor more information about runtime restarts, see [Handling Runtime Changes](/guide/topics/resources/runtime-changes).\n\nYou may be wondering what happens if you want to continue playing \"background\nmedia\" even when the user leaves your activity, much in the same way that the\nbuilt-in Music application behaves. In this case, what you need is a\n[`MediaPlayer`](/reference/android/media/MediaPlayer) controlled by a Service, as discussed in the next section\n\nLearn more\n----------\n\nJetpack Media3 is the recommended solution for media playback in your app. [Read\nmore](/media/media3) about it.\n\nThese pages cover topics relating to recording, storing, and playing back audio\nand video:\n\n- [Supported Media Formats](/guide/topics/media/media-formats)\n- [MediaRecorder](/guide/topics/media/mediarecorder)\n- [Data Storage](/guide/topics/data/data-storage)"]]