管理 MediaPlayer 状态和资源

本文档介绍了两个可能存在陷阱的方面。

  • State。对于“Medialayer”,某些操作仅在特定状态下有效。不正确的操作可能会导致异常或意外行为。

  • 资源:进行配置更改(例如屏幕旋转)时,您必须释放 MediaPlayer 对象,以释放系统资源并避免资源耗尽。

管理状态

MediaPlayer 是基于状态的。也就是说,它具有内部状态,您在编写代码时必须始终注意,某些操作仅在播放器处于特定状态时才有效。如果您在错误的状态下执行某项操作,则系统可能会抛出异常或导致其他不良行为。

MediaPlayer 类文档中的状态图说明了哪些方法可将 MediaPlayer 从一种状态变为另一种状态。例如:

  • 当您创建新的 MediaPlayer 时,它处于 Idle 状态。
  • 您可以通过调用 setDataSource() 来初始化它,这会将其更改为 Initialized 状态。
  • 您可以使用 prepare()prepareAsync() 方法进行准备。
  • MediaPlayer 准备就绪后,它便会进入 Prepared 状态,这也意味着您可以通过调用 start() 使其播放媒体内容。

此时,如图所示,您可以通过调用 start()pause()seekTo() 等方法在 StartedPausedPlaybackCompleted 状态之间切换。

不过请注意,当您调用 stop() 时,除非您再次准备 MediaPlayer,否则将无法再次调用 start()

在编写与 MediaPlayer 对象互动的代码时,请始终牢记该状态图,因为从错误的状态调用其方法是导致错误的常见原因。

释放 MediaPlayer

MediaPlayer 会占用宝贵的系统资源。因此,您应该始终采取额外的预防措施,确保 MediaPlayer 实例保留的时间不会过长。完成该操作后,您应始终调用 release() 以确保分配给它的所有系统资源均已正确释放。

例如,如果您使用的是 MediaPlayer,并且您的 activity 收到对 onStop() 的调用,则必须释放 MediaPlayer,因为在 activity 未与用户互动时保留它没有意义(除非您在后台播放媒体,下一部分将对此进行讨论)。

当然,当 activity 恢复或重启时,您需要先创建一个新的 MediaPlayer 并再次完成准备工作,然后才能恢复播放。

以下代码段介绍了如何释放并取消 MediaPlayer

Kotlin

mediaPlayer?.release()
mediaPlayer = null

Java

mediaPlayer.release();
mediaPlayer = null;

例如,思考一下:如果您忘记在 activity 停止时释放 MediaPlayer,但是在 activity 重新启动时新建一个 MediaPlayer,则可能会出现哪些问题。当用户更改屏幕方向(或以其他方式更改设备配置)时,系统会默认重启 activity。当用户在纵向和横向之间来回旋转设备时,您可能会快速耗尽所有系统资源,因为每次更改屏幕方向时,您都会创建一个新的 MediaPlayer,但从未释放。

如需详细了解运行时重启,请参阅处理运行时更改

您可能想知道:当用户离开您的 activity 后仍继续播放“后台媒体”(这与内置音乐应用的行为十分相似)会发生什么。在这种情况下,您需要的是由 Service 控制的 MediaPlayer,如下一部分中所述

了解详情

Jetpack Media3 是应用中播放媒体的推荐解决方案。了解详情

以下页面介绍了有关录制、存储以及播放音频和视频的主题: