接下來說明一下,提供歌詞播放器服務的LyricPlayerService。這個類在整個播放過程中的作用是
1.負責管理LyricAdapter的生命週期。
2.控制音樂播放,歌詞解析,並且協調音樂與歌詞同步。
3.收集超類,LyricAdapter發來的通知並傳遞給登入的LyricAdapterListener
首先是看一下這個類在全體圖中的位置。
我們可以明顯的看出這個類處於整個圖中的節點位置,光從這一點就可以理解這個類的重要性。
代碼不多,簡單說明一下。
首先是定義用於從LyricPlayerService接收狀態變化通知的介面並提供了指定具象介面的方法。
在歌曲播放過程中,繼續應用退出LyricPlayerService還會繼續執行。這時如果重新啟動播放器應用程式,就有一個重建立立聯絡,也就是播放中的LyricPlayerService指定介面的情境。在LyricPlayerService的設計中,會重新調用LyricPlayerListener的onLyricLoad和onLyricChanged方法。這樣應該可以簡化應用側的實現。
//定義接受播放器狀態變化的介面
public interface LyricPlayerListener{
//播放位置發生變化
public void onPositionChanged(long position);
//播放器狀態發生變化
public void onStateChanged();
//當前歌詞變化
public void onLyricChanged(int lyric_index);
//歌詞檔案解析完了
public void onLyricLoaded();
}
private LyricPlayerListener mLyricPlayerListener = null;
void setLyricPlayerListener(LyricPlayerListener listener){
mLyricPlayerListener = listener;
if(mLyricPlayerListener != null)
{
//新設定Listener直接調用onLyricLoad方法,給以個準備表是內容的機會。
mLyricPlayerListener.onLyricLoaded();
int curLyric = mLyricAdapter.getCurrentLyric();
if(curLyric >= 0 && curLyric < mLyricAdapter.getLyricCount()){
//如果已經處於播放中狀態,將現在歌詞通知給Listener
mLyricPlayerListener.onLyricChanged(curLyric);
}
}
}
建立LyricAdapter的執行個體
private LyricAdapter mLyricAdapter = new LyricAdapter();
建立SafetyTimer的執行個體並制定動作。在OnTimer事件中,首先取得MediaPlayer的現在播放位置並將這個語音總機給LyricAdapter和登入的mLyricPlayerListener。內容很簡單,但是這裡是LyricPlayerService能夠正常動作的最主要的部分。除了我們看不到的歌曲播放部分,這裡差不多算是半個主程式了。
private SafetyTimer mLyricTimer = new SafetyTimer(500, new SafetyTimer.OnTimeListener(){
public void OnTimer(){
if(mMediaPlayer != null){
int position = mMediaPlayer.getCurrentPosition();
if(mLyricPlayerListener != null){
mLyricPlayerListener.onPositionChanged(position);
}
mLyricAdapter.notifyTime(position);
}
}
});
onCreate和onDestroy沒有什麼特別的。當然在onDestroy裡面也可以調用mLyricAdapter.setListener(null); 沒有什麼區別。
@Override
public void onCreate() {
super.onCreate();
mLyricAdapter.setListener(this);
}
@Override
public void onDestroy() {
super.onDestroy();
mLyricAdapter = null;
}
接下來是播放控制關聯方法。主要做以下幾件事
1.調用超類的功能。
2.控制SafetyTimer的動作。
3.條用Listener的對應功能。
@Override
public void start() {
if(isStop()){
//停止狀態開始,需要重新啟動Timer
super.start();
mLyricTimer.startTimer();
}else{
//暫停狀態開始,不需要重啟Timer
super.start();
}
if(mLyricPlayerListener != null){
mLyricPlayerListener.onStateChanged();
}
}
@Override
public void stop() {
mLyricTimer.stopTimer();
super.stop();
if(mLyricPlayerListener != null){
mLyricPlayerListener.onStateChanged();
}
}
@Override
public void pause() {
super.pause();
if(mLyricPlayerListener != null){
mLyricPlayerListener.onStateChanged();
}
}
下面的兩個方法覆蓋了,超類的對應方法,把本來用來播放前後歌曲的功能改成播放同一首歌內的前後一句歌詞。
@Override
public void playNext(){
seekToNextLyric();
}
@Override
public void playPrev(){
seekToPrevLyric();
}
以下是有關歌詞的方法。基本上都是利用LyricAdapter和超類的位置控制功能。
public void loadLyric(){
String url = getDataSource();
//和歌曲在同一目錄下,相同檔案名稱,副檔名為lrc的檔案
String strLyricFileUrl = url.substring(0, url.lastIndexOf(".") + 1) + "lrc";
mLyricAdapter.LoadLyric(strLyricFileUrl);
}
public int getLyricCount(){
return mLyricAdapter.getLyricCount();
}
public String getLyric(int index){
return mLyricAdapter.getLyric(index);
}
public long seekToLyric(int index){
long position = mLyricAdapter.getLyricTime(index);
if(position != -1){
return seek(position);
}else{
return 0;
}
}
public void seekToPrevLyric(){
int curLyric = mLyricAdapter.getCurrentLyric();
if(curLyric > 0){
seekToLyric(curLyric - 1);
}
}
public void seekToNextLyric(){
int curLyric = mLyricAdapter.getCurrentLyric();
if(curLyric < mLyricAdapter.getLyricCount() - 1){
seekToLyric(curLyric + 1);
}
}
所剩不多了,重載onCompletion是想在這個時刻關閉Timer的同時,將這一變化通知個mLyricPlayerListener.
@Override
public void onCompletion(MediaPlayer mp) {
if(mLyricTimer.isRunging()){
mLyricTimer.stopTimer();
}
if(mLyricPlayerListener != null){
mLyricPlayerListener.onStateChanged();
}
super.onCompletion(mp);
}
最後是繼承LyricAdapter.LyricListener需要的兩個方法。將來自LyricAdapter的通知轉送給已經登入的mLyricPlayerLister。之所以這樣做是希望利用者在使用時可以簡單一些。
@Override
public void onLyricChanged(int lyric_index){
if(mLyricPlayerListener != null){
mLyricPlayerListener.onLyricChanged(lyric_index);
}
}
@Override
public void onLyricLoaded(){
if(mLyricPlayerListener != null){
mLyricPlayerListener.onLyricLoaded();
mLyricPlayerListener.onStateChanged();
}
}
軟體功能說明:原創:Android應用開發-Andorid歌詞秀,含源碼
工程,源碼下載:Android歌詞秀源碼,工程檔案2011/9/11版
作者“來自大連”