最近在複習Service的使用,寫了一個音樂播放器。startService不能拿到Service對象的引用,進而不能在音樂播放的過程中控件播放器,比如上一首,下一首,暫停等。于是就使用了bindService,但是使用bindService也有問題,由于bindService方式啟動的Service的生命周期和打開他的Activity一緻,就使得即使你沒有調用unbindService時,Activity退出時,service也會退出,調用onDestory。音樂就不能在背景播放了,這顯然不能滿足要求。
兩種方式都不行,但是我又不想放棄放棄bindService的特點,跑去用廣播的方式來控制音樂播放。網上搜到了有些人說使用
startService和bindService兩種方式混合使用。我嘗試這麼做了,先調用startService,再調用bindService,如下:
if (songPathList != null && songPathList.size() > 0) {
Intent bindService = new Intent(MainActivity.this, PlayService.class);
startService(bindService);
isConnected = bindService(bindService, musicServiceConnection, BIND_AUTO_CREATE);
}
跑起來試驗一下,确實可以利用bindService來控制上一曲和下一曲,并且退出的時候,音樂還在繼續播放。
對于這個現象,我有以下幾個疑問:
1. startService和bindService一起調用的時候,它們啟動的是同一個Service嗎?進而控制的是同一個播放器嗎?
2.startServie和bindService一起調用 的時候,當Activity退出的時候,Service的生命周期是怎樣的呢?
對于這兩個疑問,我做了一些試驗。我的操作步驟是:
1.首次打開app——>2.點選播放按鈕——>3.退出app——>4.再次進入app——>5.點下一首——>6.點暫停——>7.退出app
列印的日志如下:
1.
2019-04-28 15:50:50.611 4055-4055/com.demo.service D/PlayService: ---------onCreate,初始化播放器,隻執行一次
2019-04-28 15:50:50.621 4055-4055/com.demo.service D/PlayService: -------------onStartCommand,執行多次:[email protected]
2019-04-28 15:50:50.621 4055-4055/com.demo.service D/PlayService: --------------------onStart
2019-04-28 15:50:50.623 4055-4055/com.demo.service D/PlayService: -------------------onBind:[email protected]
2.
2019-04-28 15:51:24.175 4055-4055/com.demo.service D/PlayService: -----------------音樂開始播放,bindService調用的
3.
2019-04-28 15:51:40.094 4055-4055/com.demo.service D/PlayService: -------------------------onUnbind:[email protected]
4.
2019-04-28 15:52:07.919 4055-4055/com.demo.service D/PlayService: -------------onStartCommand,執行多次:[email protected]
2019-04-28 15:52:07.919 4055-4055/com.demo.service D/PlayService: --------------------onStart
5. 下一首
2019-04-28 15:52:12.580 4055-4055/com.demo.service D/PlayService: ---------------------下一首,bindService調用的
6.暫停
2019-04-28 15:55:41.950 4055-4055/com.demo.service D/PlayService: -----------------音樂暫停,bindService調用的
7.退出
無log
從上面的日志列印,我們來總結幾點結論:
1. 自始至終我們的PlayService對象都是 @1b1c6f ,這說明我們多次調用startService和bindService它們啟動的都公用同一個Service,這樣就更好控制了,不至于混亂。
2.首次進入Activity,startService和bindServie都調用,會執行startService觸發的onStartCommand和onStart方法,也會執行bindService觸發的onBind方法。
3.首次退出Activity,在MainActivity裡調用unbindService方法時,會觸發onUnbind方法,但是不觸發onDestory方法。音樂不停止。
4.再次進入Activity,調用startService和bindService時,隻會執行startService觸發的onStartCommand和onStart方法,bindService不會觸發onBind方法。
5.雖然沒有再次觸發onBind方法,但是MainActivity還是執行了onServiceConnected方法,說明Service和MainActivity還是關聯上的,還是可以使用service對象引用來控制播放器上一曲,下一曲等操作。
6.再次退出Activity時,由于進來時Service沒有調用onBind方法,這次退出onUnbind方法也沒有執行。并且onDestory方法仍然沒有執行。如上面步驟7,什麼日志都沒有列印。
下面把整個流程的日志截圖貼上來,用于友善觀看分析:
項目代碼如下:https://github.com/tomyZhou/simple_service_music_player如果對你有用,歡迎start一下,謝謝~