音乐播放时,点击seekbar,可以调整音乐播放的进度。
seekbar和音乐播放器如何处理这个“进度”关系:
当点击进度时,musicplay会先更改seekbar的显示,然后再通知mediaplay进行相应seek并播放
一、当点击进度时,musicplay会设置给seekbar,更新seekbar当前的位置(progress)
private long refreshNow() {
。。。
mProgress.setProgress(progress);
。。。。
}
ProgressBa.java
mProgress就是public class ProgressBar extends View
ProgressBar里
public synchronized void setProgress(int progress) {
setProgress(progress, false);
}
调用下面的函数
synchronized boolean setProgress(int progress, boolean fromUser) {
。。。
mProgress = progress;
refreshProgress(R.id.progress, mProgress, fromUser);
return true;
}
此函数中会调用到refreshProgress,跑doRefreshProgress
private synchronized void refreshProgress(int id, int progress, boolean fromUser) {
if (mUiThreadId == Thread.currentThread().getId()) {
doRefreshProgress(id, progress, fromUser, true);
}
。。。。
}
doRefreshProgress会调用seekBar.java中的onProgressRefresh
seekBar.java
void onProgressRefresh(float scale, boolean fromUser) {
super.onProgressRefresh(scale, fromUser);
if (mOnSeekBarChangeListener != null) {
mOnSeekBarChangeListener.onProgressChanged(this, getProgress(), fromUser);
}
}
A。super.onProgressRefresh(scale, fromUser);就是调用更改seekbar的显示位置,根据scale,这个scale时[0,1]。
B。mOnSeekBarChangeListener.onProgressChanged(this, getProgress(), fromUser);是通知musicplay更新播放位置
mOnSeekBarChangeListener是musicplay设置过来的listener。
public void setOnSeekBarChangeListener(OnSeekBarChangeListener l) {
mOnSeekBarChangeListener = l;
}
setOnSeekBarChangeListener接口函数是被musicplay调用的,设置listener到seekbar用。
二、musicplay通知media seek到相应的progress
public void onCreate(Bundle icicle)
{
....
<pre><a target=_blank class="l" name="219" href="http://10.5.2.45:8080/source/xref/sprdroid6.0_trunk/packages/apps/Music/src/com/android/music/MediaPlaybackActivity.java#219"></a>219 if (mProgress instanceof SeekBar) {
220 SeekBar seeker = (SeekBar) mProgress;
221 seeker.setOnSeekBarChangeListener(mSeekListener);
222 }
223 mProgress.setMax(1000);
}
由上面的B知道,seekbar会通过这个listener,调用onProgressChanged函数,来进行seek动作
private OnSeekBarChangeListener mSeekListener = new OnSeekBarChangeListener() {
。。。
443 public void onProgressChanged(SeekBar bar, int progress, boolean fromuser) {
447 long now = SystemClock.elapsedRealtime();
448 if ((now - mLastSeekEventTime) > 250) {
449 mLastSeekEventTime = now;
450 mPosOverride = mDuration * progress / 1000;
451 try {
452 mService.seek(mPosOverride);
453 } catch (RemoteException ex) {
454 }
。。。。。。
461 }
462 }
。。。。。
}
mService.seek(mPosOverride);就是设置media进行seek动作;
mPosOverride = mDuration * progress / 1000;是根据progress的值进行简单计算,mDuration应该是歌曲的长度,progress/1000就是比例(progress最大是1000,progress为当前位置,以1000划分的位置)。
private IMediaPlaybackService Service = null;mService是 IMediaPlaybackService,I 很熟系的东西了,通过binder调用到mediaplayback进行seek动作了。