Tôi đã xây dựng một trình phát nhạc đơn giản trong Android. Chế độ xem cho mỗi bài hát chứa SeekBar, được triển khai như sau:
public class Song extends Activity implements OnClickListener,Runnable {
private SeekBar progress;
private MediaPlayer mp;
// ...
private ServiceConnection onService = new ServiceConnection() {
public void onServiceConnected(ComponentName className,
IBinder rawBinder) {
appService = ((MPService.LocalBinder)rawBinder).getService(); // service that handles the MediaPlayer
progress.setVisibility(SeekBar.VISIBLE);
progress.setProgress(0);
mp = appService.getMP();
appService.playSong(title);
progress.setMax(mp.getDuration());
new Thread(Song.this).start();
}
public void onServiceDisconnected(ComponentName classname) {
appService = null;
}
};
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.song);
// ...
progress = (SeekBar) findViewById(R.id.progress);
// ...
}
public void run() {
int pos = 0;
int total = mp.getDuration();
while (mp != null && pos<total) {
try {
Thread.sleep(1000);
pos = appService.getSongPosition();
} catch (InterruptedException e) {
return;
} catch (Exception e) {
return;
}
progress.setProgress(pos);
}
}
Điều này hoạt động tốt. Bây giờ tôi muốn một bộ đếm thời gian đếm giây / phút tiến trình của bài hát. Vì vậy, tôi đặt một TextView
bố cục, đưa nó findViewById()
vào onCreate()
và đặt nó vào run()
sau progress.setProgress(pos)
:
String time = String.format("%d:%d",
TimeUnit.MILLISECONDS.toMinutes(pos),
TimeUnit.MILLISECONDS.toSeconds(pos),
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(
pos))
);
currentTime.setText(time); // currentTime = (TextView) findViewById(R.id.current_time);
Nhưng dòng cuối cùng cho tôi ngoại lệ:
android.view.ViewRoot $ CalledFromWrongThreadException: Chỉ chủ đề ban đầu tạo phân cấp chế độ xem mới có thể chạm vào chế độ xem của nó.
Tuy nhiên, về cơ bản, tôi đang làm điều tương tự như tôi đang làm với SeekBar
- tạo ra chế độ xem onCreate
, sau đó chạm vào nó run()
- và nó không cho tôi khiếu nại này.
error.setText(res.toString());
phương thức bên trong run (), nhưng tôi không thể sử dụng độ phân giải vì nó không phải là cuối cùng .. quá tệ