DW公版音乐记忆的解析

2023-03-24 13:40:36 浏览数 (1)

1.拔插u盘的播放记忆

对于音乐应用来说拔插U盘会收到来自TW服务发送的0x9e1f拔插数据 其中msg.arg2数据0为拔出,1为插入, 当收到0时并且确认当前正在播放的文件为插拔的U盘时,会stopMusic,并且清空临时播放列表

代码语言:javascript复制
if(msg.arg2 == 0) {
    mTW.mPlaylistRecord.clearRecord();
    stopMusic();
}

而此时的播放信息(进度,播放路径等)并未置为初始状态 所以当插入U盘时, 如果判断之前的播放路径为插入的U盘路径 则根据播放路径找到临时播放列表 然后直接进行播放即可

代码语言:javascript复制
mTW.loadFile(mContext,mTW.mPlaylistRecord, mTW.mCurrentPath);
mTW.toRPlaylist(mTW.mCurrentIndex);
if(!isPlaying() && (mTW.getService() == TWMusic.ACTIVITY_RUSEME)) {
    if(prepare(mTW.mCurrentAPath) == 0 && !isPlaying()) {
        seekTo(mTW.mCurrentPos);
        playMusic();
    }
    duck(false);
}

只要注意这种状态下播放进度的更新mCurrentPos值,不要置为0,即可保证记忆播放 还有一点要注意的是,有的平台插入U盘时,会连续发送0和1过来,需要修改为插入U盘只发送1,否则会导致播放记忆异常

2.断ACC启动的播放记忆

音乐关于播放状态的记忆形式,目前是以file文件存储的方式,这样做可以保证其他应用可以调用到保存的文件,例如主界面 保存在以下时机时更新

播放新的文件

方控停止

程序完全销毁

音乐界面退出 保存的逻辑为

代码语言:javascript复制
try {
    BufferedWriter bw = null;
    try {
        bw = new BufferedWriter(new FileWriter("/data/tw/music"));
        bw.write(mCurrentAPath);
        bw.write('n');
        bw.write(Integer.toString(mCurrentIndex));
        bw.write('n');
        bw.write(Integer.toString(mCurrentPos));
        XTLog.i(mCurrentPos);
        bw.write('n');
        bw.write(Integer.toString(mShuffle));
        bw.write('n');
        bw.write(Integer.toString(mRepeat));
        bw.write('n');
        bw.flush();
        mTW.write(0x9f1a,1,0,"sync");
    } catch (Exception e) {
        XTLog.i();
        new File("/data/tw/music").delete();
    } finally {
        if(bw != null) {
            bw.close();
            bw = null;
        }
    }
    FileUtils.setPermissions("/data/tw/music", 0666, -1, -1);
} catch (Exception e) {
    Log.i(TAG, "" e.toString());
}

保存的位置为

代码语言:javascript复制
/data/tw/music

读取的方式为TWUtils走open,也就是应用初始化的时候读取保存的播放信息更新 然后应用在走onresume的生命周期时进行记忆播放

代码语言:javascript复制
if (!isPlaying() && mTW.mSource == 0x03){
    if(prepare(mTW.mCurrentAPath) == 0) {
        seekTo(mTW.mCurrentPos);
        playMusic();
    }
}

3.退出进入音乐的播放记忆

先介绍音乐的view层与mode层的绑定逻辑 首先要明确mode是单例的,当音乐activirty启动和音乐服务启动时,都会绑定这个mode

代码语言:javascript复制
private void BindView(){
    mModel.bindMsuiclView(this,mContext);
}
public void onCreate(){
    BindView();
}

mode对应的处理是添加到一个view集合中

代码语言:javascript复制
@Override
public void bindMsuiclView(MusicModelView musicPresenter,Context context) {
    if (musicModelViews.size() == 0){
        this.mContext = context;
        onCreate();
    }
    if (!musicModelViews.contains(musicPresenter)){
        musicModelViews.add(musicPresenter);
    }
}

当音乐activity和音乐服务都退出时, 会解绑各自的对象

代码语言:javascript复制
public void onDestroy() {
    unBindView();
}
private void unBindView(){
    mModel.unBindMsuiclView(this);
}

view集合也会对应remove对应的对象

代码语言:javascript复制
@Override
public void unBindMsuiclView(MusicModelView musicPresenter) {
    if (musicModelViews.contains(musicPresenter)){
        musicModelViews.remove(musicPresenter);
    }
    if (musicModelViews.size()==0){
        onDestory();
    }
    saveData();
}

当没有view绑定mode时(musicModelViews.size()==0)mode才会自毁回收 所以当音乐activity返回退出时,其实mode对象处于被音乐服务持有运行的状态 而根据服务的生存特性,当activity销毁时服务其实还在在后台运行,

代码语言:javascript复制
@Override
protected void onDestroy() {
    mPresenter.onPause();
    mPresenter.musicPause();
    mPresenter.onDestroy();

音乐activity退出时,只做暂停和解绑处理,此时播放器仅仅是暂停状态 所以当音乐activity重新启动时,走到onresume时,会恢复退出之前的播放状态,并更新播放信息。

4.启动360状态的播放记忆

正常情况下,非断电重启时,机器会根据模式恢复程序运行,而针对一些带DVR和360的平台,例如T5,TS10, 有强制启动DVR/360的启动方式,当跟音乐同时启动时,根据机器性能和状态,有可能会导致音乐播放异常问题。 所以这时候,音乐这边是建议当判断要启动360时,音乐只以启动服务的方式运行在后台 具体的操作放在TW服务中携带一个Extra启动音乐服务

代码语言:javascript复制
startServiceAPK("com.tw.music","com.tw.music.MusicService","resume");
...
private void startServiceAPK(String pkg, String cls, String cmd) {
        try {
            Intent it = new Intent();
            it.setComponent(new ComponentName(pkg, cls));
            it.putExtra("cmd", cmd);
            startService(it);
        } catch (Exception e) {
        }
    }

音乐服务会自启播放

代码语言:javascript复制
else if ("resume".equals(cmd)){
    if (!mMusicInfo.isPlaying()){
        mPresenter.musicPlay();
    }
}

0 人点赞