媒体播放器应该在单独的线程中运行吗?

16

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

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

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

“注意:服务在其托管进程的主线程中运行——服务不创建自己的线程,也不在单独的进程中运行(除非您另外指定)。这意味着,如果您的服务将执行任何需要大量CPU或阻止操作(如MP3播放或网络),您应该在服务内部创建一个新线程来执行该工作。通过使用单独的线程,您将减少应用程序未响应(ANR)错误的风险,并且应用程序的主线程可以仍然专用于与您的活动进行用户交互。”

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


请阅读此处内容:https://dev59.com/_V_Va4cB1Zd3GeqPTGzE - Marko Niciforovic
1
我强烈建议不要在应用程序的主线程中对Audiomanager、MediaPlayer、AudioRecord等进行任何阻塞调用。如果由于某种原因音频系统暂时变得拥挤或完全停止响应,你的应用程序将会出现ANR,并且产生的错误报告对任何人都没有用处。 - Michael
感谢您的回复,@Michael!我完全同意您的观点,阻塞调用应该在单独的线程中运行。但是,我应该期望媒体播放变得阻塞吗?我只是找不到一种方法来判断媒体播放器是否正在变得“阻塞”,或者是什么原因导致了这种情况。这只发生在我通过车或火车旅行时使用rtsp进行流媒体传输。也许更换基站可能会有问题?目前,我依靠MediaPlayer来解决这个问题,大多数情况下都可以。 - smult
3
我记不清楚哪些方法是同步的,哪些是异步的。但是,如果文档没有说明一个给定的方法是异步的,那么你应该假设它可能需要很长时间才能返回结果。在大多数情况下,这段时间不会太长,不会导致应用程序发生ANR(应用程序无响应)。然而,为了避免在这些方法不能及时返回结果时(无论出于何种原因)仍然发生ANR,你不应该从主线程调用它们。 - Michael
3个回答

14

不幸的是,仅仅调用prepareAsync()是不够的,不能避免ANR提示和应用程序挂起几秒钟,特别是如果您从网络播放文件。最好的方法是将MediaPlayer实例放在自己的线程中,或者至少在Handler中执行密集的调用(如mediaplayer.start())。我已经使用MediaPlayer一年多了,可以告诉你,在不同的情况下它肯定会挂起。


0

流媒体音乐是否会导致主线程停止,直到音乐流完?这可能是它变慢的原因。

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


-2

如果你正在进行任何网络传输,你应该将其放在一个线程中,MediaPlayer并不是那么资源密集型的。将它保留在你的Activity中。


1
你不想将媒体播放器保留在活动中,因为即使活动被销毁,它也应该继续运行。你应该在前台服务中运行它。 - smult

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接