MainActivity の代わりに別のサービスで実行されるストリーミング MediaPlayer を作成しました。ユーザーが進行状況をシークしたときに SeekBar の位置を更新するために、ユーザーがシークした位置についてサービスに通知する Broadcast Receiver を使用しています。その後、サービスはシーク位置をフェッチし、MainActivity 内の SeekBar の現在の位置を更新します。
すべてが機能していますが、ユーザーが SeekBar をすばやく動かすと、サービス クラスが MainActivity の UI をフリーズさせ、クラッシュすることがあります。Service クラスから MainActivity の SeekBar を更新する最良の方法は何でしょうか?
コードサンプル、
主な活動、
// Set up constant ID for broadcast of seekbar position
public static final String BROADCAST_SEEKBAR = "com.gm.sendseekbar";
private Intent intent;
@Override
public void onProgressChanged(SeekBar sb, int progress, boolean fromUser) {
// TODO Auto-generated method stub
if (fromUser) {
int seekPos = sb.getProgress();
intent.putExtra("seekpos", seekPos);
sendBroadcast(intent);
}
}
サービスクラス、
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
mp = new MediaPlayer();
mp.setOnBufferingUpdateListener(this);
mp.setOnCompletionListener(this);
mp.setOnInfoListener(this);
mp.setOnPreparedListener(this);
mp.setOnSeekCompleteListener(this);
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Set up receiver for seekbar change
registerReceiver(broadcastReceiver, new IntentFilter(
ActivityMain.BROADCAST_SEEKBAR));
}
// Receive seekbar position if it has been changed by the user in the main activity
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
sendBufferStartBroadcast();
updateSeekPos(intent);
}
};
// Update seek position from Activity
public void updateSeekPos(Intent intent) {
int seekPos = intent.getIntExtra("seekpos", 0);
if (mp.isPlaying()) {
int playPositionInMillisecconds = (mediaFileLengthInMilliseconds / 100)
* seekPos;
mp.seekTo(playPositionInMillisecconds);
}
}