Android 音樂播放器的實現(三)Service的實現

來源:互聯網
上載者:User

Android 界一直流傳著一句話,想學習Service, 那麼你就要寫一個音樂播放器。

為什麼要用 Service?

Service 是運行於幕後的,它並不輕易見人,而正巧,音樂也是只聞其聲不見其人的,相信這就是它們在一起的原因。

大家都知道,從Activity中跟Service互動有兩種方式:

1)startService。在Activity 中直接調用 startService的方法,我們就可以在後台看不見的地方(但還是在同一個進程裡)建立一個叫Service 的東西,它能夠在後面靜悄悄地執行類似下載的任務,也能夠熱熱鬧鬧地唱起“蒼茫的天涯是你的愛...”,但是這種方式呢,我們就只能跟它說,“Service,做這件事吧”,而沒辦法在它做一半的時候跟它說,“Service,別做這事了,做那一件事吧”(其實也可以,但是每次都要重新建立一個Intent,裡面定義我們要做的事情,然後再次調用startService,讓它重新再做,但我覺得,這不科學)。

2)bindService。我們也可以通過 bindService的方法來將Activity 跟 Service 綁定在一起,為什麼綁定Service了之後就能夠隨時叫Service做事了呢?因為通過綁定,從Service返回了一個繼承於Binder的類給Activity,而通過這個繼承類,可以在裡面定義一些互動的回呼函數,那麼Activity就可以通過這些方法來隨時告訴Service要做些啥事了,這才叫互動嘛。

那麼,音樂播放器肯定是要用後面這種 bindService的方法了啊,因為我們要互動啊。先看一下介面:


在列表介面上和歌詞介面上有著不同的控制按鈕,比如向前向後,模式改變,播放暫停等,所以我們得想想怎麼去設計Service。

如何設計Service?我把 Service 分成三種情況:1)要響應 Activity 中按鈕的控制;2)Service中自己要控制的邏輯,比如一首歌播放完之後,要自動播放下一首等;3)要能夠主動地去通知Activity。
第一種情況,其實就是我們要在Binder中定義的介面啦,響應列表介面的唱停前後和模式變換。
class NatureBinder extends Binder{/** * 唱吧,有人想聽 */public void startPlay(int currentMusic, int currentPosition){}/** * 別唱了 */public void stopPlay(){}/** * 後一首 */public void toNext(){}/** * 前一首 */public void toPrevious(){}/** * 有人改變模式了,我得把它記下來  */public void changeMode(){}/** * 告訴別人,你現在到底是順序播放,還是隨機亂彈 * MODE_ONE_LOOP = 1; * MODE_ALL_LOOP = 2; * MODE_RANDOM = 3; * MODE_SEQUENCE = 4;  * @return */public int getCurrentMode(){}/** * 告訴調用者,到底有沒有在做事。。。 * @return */public boolean isPlaying(){}/** * 要告訴調用者,當前播哪首歌了,歌多長啊 */public void notifyActivity(){}/** * 有人拖動Seekbar了,要告訴service去改變播放的位置 * @param progress */public void changeProgress(int progress){}}

那麼第二種情況,就是servcie本身的邏輯控制了,其實主要的邏輯是當一首歌播放完了,它得自己去判斷下一首要播什麼,還有沒有得播啊,所以我們要實現MediaPlayer的OnCompletionListener方法,在這裡,我們要實現下一步該怎麼做,繼續播呢,還是停下來,要不要通知清單介面,我換歌了。。。
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {@Overridepublic void onCompletion(MediaPlayer mp) {...});}

而第三種情況,就是怎麼去通知清單介面了。在這裡是通過發送廣播的方式,而Activity中會註冊相應的廣播過濾器來接收Service中發送出去的訊息,比如歌曲播放的進度,換歌了之類的。下面的代碼是告訴前台,我現在播到哪個位置了,你給我更新一下進度條的位置。
private void toUpdateProgress(){if(mediaPlayer != null && isPlaying){int progress = mediaPlayer.getCurrentPosition();Intent intent = new Intent();intent.setAction(ACTION_UPDATE_PROGRESS);intent.putExtra(ACTION_UPDATE_PROGRESS,progress);sendBroadcast(intent);handler.sendEmptyMessageDelayed(updateProgress, 1000);}}

而相對應的,我們在Activity中,會接收到這樣的廣播,從而做相應的更新,當然,也別忘了要註冊對應的Action,不然可收不到。代碼如下:
private void registerReceiver(){progressReceiver = new ProgressReceiver();IntentFilter intentFilter = new IntentFilter();intentFilter.addAction(NatureService.ACTION_UPDATE_PROGRESS);...registerReceiver(progressReceiver, intentFilter);}//上面是註冊廣播,下面是接收廣播,最後別忘了,要登出廣播...class ProgressReceiver extends BroadcastReceiver{@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if(NatureService.ACTION_UPDATE_PROGRESS.equals(action)){int progress = intent.getIntExtra(NatureService.ACTION_UPDATE_PROGRESS, 0);if(progress > 0){currentPosition = progress; // Remember the current positionpbDuration.setProgress(progress / 1000);}...}}

既然已經把Service 該幹什麼都想好了,那麼很顯然下一步,就是來調用Service了嘛。Service該怎麼用?廢話!當然是在Activity中調用了。沒錯,就是這樣,在Activity中我們通過BindService來獲得一個Binder,然後就可以通過Binder來跟Service眉來眼去地交流了。
private NatureBinder natureBinder;private ServiceConnection serviceConnection = new ServiceConnection() {@Overridepublic void onServiceDisconnected(ComponentName name) {}@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {natureBinder = (NatureBinder) service;}};private void connectToNatureService(){Intent intent = new Intent(MainActivity.this, NatureService.class);bindService(intent, serviceConnection, BIND_AUTO_CREATE);}

當然,也是有幾步要走的:1)建立一個ServiceConnection 對象,在其onServiceConnected方法中返回我們的Binder。 2)就是調用bindService了,將serviceConnection作為參數傳進去。就是這麼簡單,接下來,就可以拿binder來做事了。比如播放:
natureBinder.startPlay(currentMusic,currentPosition);
暫停:
natureBinder.stopPlay();
下一首:
natureBinder.toNext();

是的,就是這樣。 差點忘了,請點擊源碼下載:

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.