2012-01-18 45 views
9

所以,我在一個單獨的線程中流式傳輸音樂。如果我離開應用程序(onPause()onStop()被調用等),音樂繼續播放,但最終 - 打開其他應用程序並在它們之間切換並返回主屏幕後 - 我的應用程序被終止。沒有崩潰,只有在logcat中的WIN DEATHprocess com.myapp.android has died。顯然,系統爲了回收資源而銷燬應用程序是合法的。MediaPlayer在單獨的線程vs在服務中通過startForeground()運行

我的問題是:是否在主線(UI)線程中運行線程意味着它現在的系統所關注的優先級較低?意思是說,比起我在Service中運行媒體播放器,甚至使用startForeground()使服務在前臺運行,它更有可能被殺死嗎?

任何想法或澄清將不勝感激!

編輯

此外,在服務的文件的一部分混淆了我。在相關部分,它指出:

注意:一種服務,它的託管過程中 服務的主線程中運行不創建自己的線程,並在 單獨的進程不會運行(除非指定)。這意味着,如果您的服務將執行任何CPU密集型工作或阻止 操作(如MP3播放或聯網),則應在服務中創建一個 新線程來完成此項工作。

我一直在主線程的服務中運行MP3播放,UI仍然響應。如果我應該按照上述引用中的建議將它放入單獨的線程中,那麼我將不會返回到我開始的位置,即媒體播放出現在主線程中,從而增加播放的可能性在其他應用程序打開時會被殺死,等等?

回答

2

我認爲你的問題大部分都在Android documentation on Services回答。

從鏈接:

前臺服務是一個被認爲是東西 用戶正在積極瞭解並因此不能對系統 候選人殺時內存不足的服務。前臺服務必須爲位於「正在進行」 標題下的狀態欄提供 通知,這意味着除非 服務停止或從前臺移除,否則不能撤消通知。

要回答你的問題,是的,運行一個單獨的Thread關閉的Activity的是要擁有比Service較低的優先級在前臺運行,即使啓動Thread已經停止Activity /暫停。

就個人而言,我建議在Service這樣做,因爲這正是Service類創建的類。

編輯:

有趣的是,你有什麼建議似乎相反的是我已經閱讀(中Service不使用線程時,一切響應)。無論如何,它可能應該在後臺線程中啓動。

線程(您創建的線程)不會死亡,除非進程死亡,並且在運行時決定需要資源時會發生。 Activity當他們不在前臺時可以被殺死,所以他們的Thread也可以被銷燬。如果您有一個Service標記爲前景,它不太可能被破壞,因此,你不應該有同樣的問題。

+0

謝謝!你能解決我的編輯? – LuxuryMode 2012-01-18 19:03:10

+1

我已經將我的mediaplayer放置在一個服務中,並且在其自己的線程中運行。如果它需要更多資源,Android將會終止媒體播放器,無論它位於何處。並且在具有前臺優先級的服務中被殺死的可能性要比在單獨的線程中更少。似乎永遠不會遇害的唯一地方就是目前處於前臺的活動。 – AndroidDev 2013-07-25 06:32:06

-1

有沒有必要從一個線程運行的MediaPlayer。只要您使用MediaPlayer.prepareAsync而不是MediaPlayer.prepare,MediaPlayer上就沒有任何方法可以阻塞足夠長的時間來解決問題。在您的服務的前臺線程上運行它。

如果你的進程就會被殺死,螺紋用下去。如果您調用Service.startForeground方法(並在狀態欄上顯示由startForeground請求的必需通知),則託管「服務」的進程的壽命比「活動」的壽命更長。一旦活動暫停,整個過程成爲回收的主要候選對象(假設過程中也沒有前臺服務)。

+4

不幸的是,雖然文檔似乎表明prepareAsync()足夠好,但還不夠。除prepare()以外的其他調用可能會掛起該應用程序,因此MediaPlayer實例最好在它自己的線程中。 – ajacian81 2013-06-12 13:04:15

7

我只是張貼了這個答案的一部分,在其他地方,但它仍然是相關的。

不幸的是,調用prepareAsync()並不足以避免ANR提示和應用程序掛起幾秒鐘,尤其是在從網絡播放文件時。最好的辦法是將MediaPlayer實例放入其自己的線程中,或者至少在處理程序中執行密集型調用(如mediaplayer.start())。我已經使用了MediaPlayer一年多了,我可以告訴你,根據具體情況,它會在各種調用之後肯定掛起。

理想情況下,你應該產卵控制從服務您的MediaPlayer的一個線程。這樣,您可以確保您的媒體在您的應用程序處於後臺時繼續播放,並且除prepare()/ prepareAsync()之外的任何阻止調用都不會掛起您的應用程序。

+1

我同意。不過,我必須補充說,即使在服務產生的線程中,我也看到mediaplayer會被終止。看起來mediaplayer有自己的內部線程,比前臺服務的優先級更低,並且Android更願意在終止服務之前終止衍生的線程。 – AndroidDev 2013-07-25 06:39:26

+0

所以,我認爲這個問題比接受的更好。無論如何,我想知道的是,即使在服務中需要運行單獨的線程嗎?目前,我正在使用完全不同的流程,但希望將其移至主流程。 – frostymarvelous 2014-11-09 21:11:49

+0

默認情況下,服務在主UI線程上運行。我們可以在服務中創建一個Thread/AsyncTask。這幾乎是我會這樣做的。 – ajacian81 2014-11-10 15:26:14

相關問題