【问题标题】:Should a MediaPlayer run in separate thread?MediaPlayer 应该在单独的线程中运行吗?
【发布时间】:2013-03-27 12:17:10
【问题描述】:

我正在构建一个从网络服务器流式传输音乐的应用程序。该应用程序具有使用 MediaPlayer 进行播放的前台服务。

我的代码基于这个例子:http://developer.android.com/guide/topics/media/mediaplayer.html

在示例中,除了 prepareAsync() 调用外,没有任何线程。让我困惑的是,当我阅读有关 Service 类的信息时,我发现了以下信息:

“警告:服务在其宿主进程的主线程中运行——该服务不会创建自己的线程,也不会在单独的进程中运行(除非您另外指定)。这意味着,如果您的服务将执行任何 CPU 密集型工作或阻塞操作(例如 MP3 播放或网络),您应该在服务中创建一个新线程来完成这项工作。通过使用单独的线程,您将降低应用程序无响应的风险(ANR) 错误,并且应用程序的主线程可以保持专用于用户与您的 Activity 的交互。”

我问的原因是应用程序有时(通常在失去连接时)在流式传输音频时冻结 UI。我完全理解如果服务使 CPU 密集工作,UI 会冻结,因为活动和服务在同一个线程上运行。但是,我应该期望 MediaPlayer 如此激烈吗?也就是说,它应该在单独的线程上运行吗?

【问题讨论】:

  • 我绝对建议不要从应用程序的主线程对 Audiomanager、MediaPlayer、AudioRecord 等进行任何阻塞调用。如果音频系统由于某种原因暂时陷入困境 - 或完全停止响应 - 您最终会在应用中收到 ANR,以及可能对任何人都没有用的错误报告。
  • 感谢您的回复@Michael!我完全同意你的阻塞调用应该在一个单独的线程中运行。但是,我应该期望媒体播放成为阻塞吗?我只是找不到方法来判断媒体播放器是否正在“阻塞”或者是什么原因造成的。仅当我在乘汽车或火车旅行时通过 rtsp 流式传输时才会发生这种情况。也许更换手机信号塔可能是个问题?目前,我依靠 MediaPlayer 来解决这个问题,这在大多数情况下都是如此。
  • 我不记得哪些方法是同步的,哪些不是。但是如果文档没有说明给定的方法是异步的,你应该假设它可能需要无限的时间才能返回。在大多数情况下,该时间不足以导致应用 ANR。但是,为了避免 ANR,即使在这些方法没有立即返回(无论出于何种原因)的情况下,您也不应该从主线程调用它们。

标签: android multithreading service streaming media-player


【解决方案1】:

不幸的是,调用 prepareAsync() 根本不足以避免 ANR 提示和您的应用程序挂起几秒钟,尤其是当您正在播放来自网络的文件时。您最好的选择是将您的 MediaPlayer 实例放在它自己的线程中,或者至少在处理程序中执行密集调用(如mediaplayer.start())。我已经使用 MediaPlayer 一年多了,我可以告诉你,它在多次通话后肯定会挂起,具体取决于具体情况。

【讨论】:

    【解决方案2】:

    流音乐是否会导致主线程停止,直到音乐完成流式传输?这可能就是它正在减慢速度的原因。

    我不是专家,目前正在自学,但值得考虑。

    【讨论】:

      【解决方案3】:

      不,如果您正在进行任何网络传输,则应将其保留在线程中,媒体播放器不会占用大量资源。把它放在你的活动中。

      【讨论】:

      • 您不希望将媒体播放器保留在活动中,因为即使活动被破坏,它也应该运行。您应该在前台服务中运行它。
      猜你喜欢
      • 1970-01-01
      • 2023-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多