Question:
I created a seekBar
to see the progress of my audio that is running in MediaPlayer
, but of all the methods I used to update the seekBar
, the only one that worked was this one below:
new Timer().schedule(new TimerTask() {
@Override
public void run() {
mySeekBar.setProgress(mp.getCurrentPosition());
}
}, 0, 1000);
All the others, such as those mentioned below, did not work.
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
mySeekBar.setProgress(mp.getCurrentPosition());
}
}, 1000);
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
mySeekBar.setProgress(mp.getCurrentPosition());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
new Thread(new TimerTask() {
@Override
public void run() {
try {
Thread.sleep(1000);
runOnUiThread(new TimerTask() {
@Override
public void run() {
mySeekBar.setProgress(mp.getCurrentPosition());
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
So, I would like to know why the others don't work, because, for me, they all should work. Here is the full app code:
package com.gabrielm.testseekbar;
import android.media.MediaPlayer;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.SeekBar;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity extends AppCompatActivity {
SeekBar mySeekBar;
Button btnPlay;
MediaPlayer mp;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mySeekBar = (SeekBar) findViewById(R.id.mySeekBar);
btnPlay = (Button) findViewById(R.id.btnPlay);
mp = MediaPlayer.create(this, R.raw.sleep);
mySeekBar.setMax(mp.getDuration());
new Timer().schedule(new TimerTask() {
@Override
public void run() {
mySeekBar.setProgress(mp.getCurrentPosition());
}
}, 0, 1000);
btnPlay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mp.start();
}
});
mySeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
Log.i("Audio position", Integer.toString(progress));
mp.seekTo(progress);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
}
Answer:
Codigo 1:
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
mySeekBar.setProgress(mp.getCurrentPosition());
}
}, 1000);
It doesn't do what you intend because SeekBar is only updated once, postDelayed(Runnable r, long delayMillis) runs Runnable r
once with a delay of 1000 milliseconds.
This can be solved by adding the Runnable again to the queue inside the run()
method:
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
mySeekBar.setProgress(mp.getCurrentPosition());
handler.postDelayed(this, 1000);
}
}, 1000);
Code 2:
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
mySeekBar.setProgress(mp.getCurrentPosition());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
It doesn't work because the code is never executed: the start()
method of the Thread remains to be called. Fixed this would not work either because it is only allowed to change Views in UIThread . On the other hand the run()
method would only be called once.
Code 3:
new Thread(new TimerTask() {
@Override
public void run() {
try {
Thread.sleep(1000);
runOnUiThread(new TimerTask() {
@Override
public void run() {
mySeekBar.setProgress(mp.getCurrentPosition());
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
The code doesn't compile, the Thread constructor receives a Runnable and not a TimerTask .
As in code 2, the start()
method still needs to be called, besides that it would only work once, however, it solves the UIThread issue, using the runOnUiThread()
method.