MediaPlayer在单独的线程中与在服务中通过startForeground()运行

Lux*_*ode 9 android

所以,我是在一个单独的线程中播放音乐.如果我离开应用程序(onPause(),onStop()被调用等),音乐将继续播放,但最终 - 打开其他应用程序并在它们之间切换并返回主屏幕 - 我的应用程序被杀死.没有崩溃,只是一个WIN DEATH和process com.myapp.android has died在logcat中.显然,系统为了回收资源而销毁应用程序是合法的.

我的问题是:在主(UI)线程的线程中运行东西是否意味着它现在具有较低的优先级,就系统而言?这意味着,它是否比我在运行媒体播放器Service甚至用于startForeground()使服务在前台运行更可能被杀死?

任何想法或澄清将不胜感激!

编辑

此外,部分服务文档让我感到困惑.在相关部分,它指出:

警告:服务在其托管进程的主线程中运行 - 该服务不会创建自己的线程,也不会在单独的进程中运行(除非您另行指定).这意味着,如果您的服务要进行任何CPU密集型工作或阻止操作(例如MP3播放或网络),您应该在服务中创建一个新线程来完成这项工作.

我总是在主线程的服务中运行MP3播放,并且UI保持响应.如果我应该把它放在上面引文中推荐的一个单独的线程中,那么我最终不会回到我开始的地方,即主要线程发生媒体播放,从而增加了回放的可能性打开其他应用程序等时被杀?

aja*_*n81 8

我刚刚在其他地方发布了这个答案的一部分,但它仍然相关.

不幸的是,调用prepareAsync()根本不足以避免ANR提示和你的应用程序挂起几秒钟,特别是如果你正在从网络播放文件.最好的办法是将MediaPlayer实例放在自己的线程中,或者至少在Handler中执行密集调用(如mediaplayer.start()).我已经使用MediaPlayer超过一年了,我可以告诉你它肯定会在各种电话后挂起,具体取决于具体情况.

理想情况下,您应该从服务中生成一个控制MediaPlayer的线程.这样,您可以确保在应用程序处于后台时继续播放媒体,任何阻止调用(除了prepare()/ prepareAsync())都不会挂起您的应用.

  • 我同意。但是我必须补充一点,即使在从服务产生的线程中,我也看到 mediaplayer 被终止。看起来 mediaplayer 有自己的内部线程,它的优先级比前台服务更低,而且 Android 更愿意在终止服务之前杀死一个生成的线程。 (2认同)

nic*_*ild 2

我认为您的大部分问题都在关于 Services 的 Android 文档中得到了解答。

从链接:

前台服务被认为是用户主动感知的服务,因此不适合在内存不足时被系统杀死。前台服务必须为状态栏提供通知,该通知位于“正在进行”标题下,这意味着除非服务停止或从前台删除,否则无法取消通知。

要回答您的问题,是的,如果启动的已停止/暂停,则单独运行Thread的优先级Activity将低于Service在前台运行的优先级。ActivityThread

就我个人而言,我建议在 a 中执行此操作,因为这正是创建Service该类的目的。Service

编辑:

有趣的是,你的建议似乎与我读到的相反(当不使用线程时,一切都是响应式的Service)。无论如何,它可能应该在后台线程中启动。

除非进程终止,否则线程(您创建的线程)不会终止,并且当运行时决定需要资源时,就会发生这种情况。 Activity当它们不在前台时可以被杀死,因此它们的Thread也可以被销毁。如果你有一个Service标记为前景,它被破坏的可能性较小,因此,你不应该遇到同样的问题。

  • 我已将媒体播放器放置在服务内部和在其自己的线程中运行的服务外部。如果 Android 需要更多资源,无论媒体播放器位于何处,Android 都会杀死它。在具有前台优先级的服务中,它被杀死的可能性并不比在单独的线程中更小。它似乎永远不会被杀死的唯一地方是当前处于前台的活动。 (2认同)