当前位置:操作系统 > 安卓/Android >>

Android歌词秀设计思路(2)歌词处理

这次的内容是歌词处理模块LyricAdapter类。这个类的主要功能有
1.歌词文件的解析
2.对外提供歌词访问服务(歌词数取得,歌词内容,时间的取得等)
3.根据播放位置检索对应的歌词。
4.在歌词文件取得后和当前歌词变化以后通过登录的LyricListener进行通知。
 
先看看LyricAdapter类在整个软件中的位置。

从图中可以看出,LyricAdapter类和SafeTimer类一样,归LyricPlayerService管理,并位置提供服务。
 
接下来在说明LyricAdapter的功能之前,先让我们看看我们的处理对象,歌词文件的内容。打开一个歌词文件(*.lrc)可以看到以下内容。
[ti:δ֪]  
[ar:]  
[al:Family Album, U.S.A.]  
[by:SPJ]  
[00:00.97]EPISODE 12    You're Tops  
[00:06.20]ACT II  
[00:10.52]Sam, would you come in, please?  
[00:16.62]You sound like something's bothering you, Susan.  
[00:19.15]The sketches for the cover of the new doll book?  
[00:21.74]That's not it.  
[00:23.35]Please sit down.  
[00:24.56]Sure.  
[00:30.31]I need your advice on a personsal matter,  
[00:32.53]but it's not about me.  
[00:35.12]You need my advice on a personal matter,  
[00:36.89]and it's not about you. OK.  
[00:40.01]It's about my grandfather.  
[00:42.62]What's the problem?  
[00:45.17]It won't sound like a big deal, 
 
除了前面的几个特殊的ti,ar,al,by等关键字以外的每一句歌词都是有包含在中括号中的时间和后面的歌词组成的。歌词处理模块的功能就是解析歌词文件并按照歌曲播放的时间选择合适的歌词表示就可以了。
 
下面来看一看今天的主角和配角吧。

LyricAdapter类主要提供以下功能
解析歌词文件并管理得到的信息。
提供访问歌词的接口(歌词语句数,取得特定歌词信息等)
根据提供的时间选择合适的歌词并将结果通知给LyricPlayerServie类。
 
SafetyTimer类主要提供以下功能
负责定时启动从MediaPlayer取得播放的当前时间并传达给LyricAdapter
 
LyricPlayerService类主要提供以下功能
负责控制LyricAdapter,SafetyTimer的创建
建立LyricPlayerService,LyricAdapter,SafetyTimer之间的联系。
控制LyricAdapter,SafetyTimer的动作
处理传出的LyricAdapter通知
 
以下是时序图

在这个时序图中,为了说明LyricAdapter的功能,我们省略了许多细节。下面是时序图的说明。
1.创建对象并建立联系
1-1 LyricPlayerService创建MediaPlayer对象
1-2 LyricPlayerService创建LyricAdapter对象
1-3 LyricPlayerService创建SafetyTimer.OnTimerListener的匿名内嵌派生类
1-4 LyricPlayerService创建SafetyTimer并指定前一步创建的SafetyTimer.OnTimerListener
1-5 LyricPlayerService将自己指定成LyricAdapter的listener.
 
2.解析歌词
2-1 LyricPlayerService调用LyricAdapter.LoadLyric方法,参数为字幕文件的文件路径+文件名。
2 -2 LyricAdapter在LoadLyric的最后会调用LyricPlayerService.onLyricLoaded方法进行通知。
 
3.启动Timer并处理播放时间通知
3-1 在启动播放器的同时启动SafetyTimer
3-2 当定时时间到了已有,SafetyTimer会调用在1-3中创建的OnTimeListener对象的OnTimer方法。
3-3 在OnTimer方法中,OnTimeListener首先从MediaPlayer取得现在的播放位置,然后调用LyricAdapter的notifyTime方法将位置传递个LyricAdapter。
3-4 LyricAdapter根据播放位置取得当前的歌词并通知LyricPlayerService进行相应的处理。
 
 
需要补充一点,在这里我们定义了一个LyricListener接口实现了,既可以将消息通知给LyricPlayerService有避免了LyricAdapter对LyricPlayerService的依赖关系。这一点和Andorid歌词秀设计思路(1)SafetyTimer中用到的是一样的方法。
以下是LyricAdapter的代码,请参考。很简单的。
package LyricPlayer.xwg; 
 
import java.io.BufferedReader; 
import java.io.FileNotFoundException; 
import java.io.FileReader; 
import java.io.IOException; 
import java.util.ArrayList; 
import java.util.Collections; 
import java.util.Comparator; 
 
import android.util.Log; 
 
public class LyricAdapter{ 
    private ArrayList<LyricLine> mLyricLines= null; 
    private LyricListener mListener = null; //歌词载入,变化Listener 
    private int mCurrentLyric = 0;   //当前的歌词 
    private int mLyricOffset = -300; //为了解决播放滞后的问题设置的调整时间,单位是毫秒 
    private static final String TAG = new String("LyricAdapter"); 
 
    //用于向外通知歌词载入,变化的Listener 
    public interface LyricListener{ 
        public void onLyricChanged(int lyric_index); 
        public void onLyricLoaded(); 
    } 
     
    //歌词信息 
    private class LyricLine{ 
        long mLyricTime;  //in milliseconds 
        String mLyricText; 
        LyricLine(long time, String lyric){ 
            mLyricTime = time; 
            mLyricText = lyric; 
        } 
    } 
     
    //将歌词的时间字符串转化成毫秒数的Utility类,如果参数是00:01:23.45 
    private static class TimeParser{ 
        //@return value in milliseconds. 
        static long parse(String strTime){ 
            String beforeDot = new String("00:00:00"); 
            String afterDot = new String("0"); 
             
            //将字符串按小数点拆分成整秒部分和小数部分。 
            int dotIndex = strTime.indexOf("."); 
            if(dotIndex < 0){ 
                beforeDot = strTime; 
            }else if(dotIndex == 0){ 
                afterDot = strTime.substring(1); 
            }else{ 
                beforeDot = strTime.substring(0, dotIndex);//00:01:23 
                afterDot = strTime.substring(dotIndex + 1); //45 
  &nb

补充:移动开发 , Android ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,