管理 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
Java
mediaPlayer.release();
mediaPlayer = null;
舉例來說,如果您在活動停止時忘記釋放 MediaPlayer
,但在活動重新啟動時建立新的 MediaPlayer
,就會發生問題。當使用者變更螢幕方向 (或以其他方式變更裝置設定) 時,系統會預設重新啟動活動。當使用者在直向和橫向之間來回旋轉裝置時,您可能會快速耗用所有系統資源,因為每次變更螢幕方向時,您都會建立一個永遠不會釋出的 MediaPlayer
。
如要進一步瞭解如何重新啟動執行階段,請參閱「處理執行階段變更」。
您可能會想知道,如果想在使用者離開活動後繼續播放「背景媒體」,會發生什麼情況,這與內建的音樂應用程式行為非常相似。在這種情況下,您需要由服務控制的 MediaPlayer
,詳情請見下一節
瞭解詳情
如要在應用程式中播放媒體,建議您採用 Jetpack Media3 解決方案。請參閱更多資訊。
以下頁面將說明錄製、儲存及播放音訊和影片的相關主題:
這個頁面中的內容和程式碼範例均受《內容授權》中的授權所規範。Java 與 OpenJDK 是 Oracle 和/或其關係企業的商標或註冊商標。
上次更新時間:2025-07-27 (世界標準時間)。
[[["容易理解","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 (世界標準時間)。"],[],[],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)"]]