2013-12-12 45 views
0

我開始在媒體播放器上播放音樂,我想知道爲什麼媒體播放器可以繼續工作,即使線程已經死亡。這裏是例子:爲什麼MediaPlayer即使在胎面結束後仍可以工作?

public class MusicThread extends Thread { 
    MediaPlayer mp; 
    public MusicThread(Context context) { 
     mp = MediaPlayer.create(context, R.raw.music); 
    } 

    @Override 
    public void run() { 
     mp.start(); 
     Log.d("MusicThread", "mp started"); 
    } 
} 

那麼活動中:

MusicThread musicThread = new MusicThread(this); 
musicThread.start(); 

這裏是我的困惑:

musicThread.start(),音樂開始。此外,線程完成,因爲我們可以看到Log.d(...)LogCat中生成的日誌,我們可以看到由musicThread.isAlive()返回的false

我有musicThread的引用,因此它在完成時不會立即執行GC。

但是mediaplayer呢?它繼續工作,但它所駐留的線程已經死亡。在這種情況下,它似乎處於一種奇怪的狀態。它還在musicThread中工作嗎?如果是,爲什麼以及如何?如果不是,它在哪裏?

回答

2

mp.start()不是阻塞呼叫。所以你的線程不會等到遊戲結束。 mp.start()呼叫立即返回。你甚至不需要一個單獨的線程來調用它。

PS:如果您想在播放完成時獲得回調,請使用setOnCompletionListener。一旦玩完,public void onCompletion(MediaPlayer mp)將被稱爲

+0

非常感謝答案!我可以知道你在哪裏發現mp.start()不是同步調用嗎?我查看了文檔,但沒有找到像這樣的陳述。非常感謝! – xwb1989

+2

@ xwb1989:實際上'start()'是一個同步方法,雖然它不是'阻塞'方法。我認爲沙希卡的措辭是誤導性的。 'start()'方法將返回而不會阻塞調用線程,但是'MediaPlayer'使用它自己的線程進行回放。 – Squonk

+0

是的,在文件中沒有清楚說明。但在這裏http://developer.android.com/guide/topics/media/mediaplayer.html#preparingasync它說「永遠不要從你的應用程序的UI線程調用prepare()」。一旦mediaplayer準備好了,我們甚至可以在UI線程中啓動它。 – Shashika

相關問題