하칸이 제안했듯이 UI 스레드에서 모든 UI 업데이트를 수행해야합니다. Handler
이 이미 있으므로 handleMessage()
메소드를 재정 의하여 UI 업데이트를 수행하면됩니다. 귀하의 코드는 다음과 같습니다.
private static final int PROGRESS_UPDATE = 0;
...
mProgress = (ProgressBar) findViewById(R.id.progressBar1);
// final long trackDuration = (musicLength/44100)*1000; // track duration in millisec
// Start lengthy operation in a background thread
new Thread(new Runnable() {
public void run() {
//Log.i("music length = ", trackDuration+"");
while (mProgressStatus < musicLength) {
mProgressStatus = audioTrack.write(music, 0, musicLength);
// Update the progress bar
Message msg = Message.obtain();
msg.what = PROGRESS_UPDATE;
msg.arg1 = mProgressStatus;
mHandler.sendMessage(msg);
}
}
}).start();
...
Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch(msg.what){
case PROGRESS_UPDATE:
mProgress.setProgress(msg.arg1);
break;
default:
Log.e("MyTag","Unsupported message type");
break;
}
}
}
감사합니다. dave.c 나는 스팀 모드에서 정적 모드로 바 꾸었습니다. 또한 트랙에서 재생을 호출하기 전에 트랙에 데이터를 기록했습니다. 진행률 표시 줄 업데이트를 처리하는 실행 파일에서 play를 호출했습니다. 응용 프로그램은 오디오 샘플을 재생하지만 진행률 막대는 여전히 움직이지 않습니다. 수정안을 보여주는 아래 코드를 게시 할 것입니다. 왜 진행 표시 줄이 움직이지 않는지에 대한 아이디어가 있습니까?
// Get the length of the audio stored in the file (16 bit so 2 bytes per short)
// and create a short array to store the recorded audio.
musicLength = (int)(file.length()/2);
final short[] music = new short[musicLength];
Log.i("filename length", file.length()+""+file.getName());
try {
// Create a DataInputStream to read the audio data back from the saved file.
InputStream is = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(is);
DataInputStream dis = new DataInputStream(bis);
// Read the file into the music array.
int i = 0;
while (dis.available() > 0) {
//music[musicLength-1-i] = dis.readShort();
music[i] = dis.readShort();
i++;
}
Log.i("buffer with "+ file.getName(), music.length+" passed in from array");
// Close the input streams.
dis.close();
// Create a new AudioTrack object using the same parameters as the AudioRecord
// object used to create the file.
audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
44100,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT,
musicLength,
AudioTrack.MODE_STATIC);
Log.i("audio instance = ", ""+audioTrack.getState());
// Start playback
//audioTrack.play();
mProgress = (ProgressBar) findViewById(R.id.progressBar1);
// final long trackDuration = (musicLength/44100)*1000; // track duration in millisec
// Start lengthy operation in a background thread
new Thread(new Runnable() {
public void run() {
//Log.i("music length = ", trackDuration+"");
while (mProgressStatus < musicLength) {
mProgressStatus = audioTrack.write(music, 0, musicLength);
// Update the progress bar
mHandler.post(new Runnable() {
public void run() {
audioTrack.play();
mProgress.setProgress(mProgressStatus);
}
});
Message msg = Message.obtain();
msg.what = PROGRESS;
msg.arg1 = mProgressStatus;
mHandler.sendMessage(msg);
}
}
}).start();
mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch(msg.what){
case PROGRESS:
mProgress.setProgress(msg.arg1);
break;
default:
Log.e("MyTag","Unsupported message type");
break;
}
}
};
} catch (Exception e) {
e.printStackTrace();
Log.e("AudioTrack","Playback Failed");
}
}
@ dave.c 안녕하세요, 내 처리기 내 UI 스레드 개인 필드가 있지만 atill 작동하지 않습니다. mhandler.sendMessage 및 mHandler.post (new Runnable()는 핸들러를 통해 UI 스레드를 업데이트) 동일한 작업을 수행하지 않아야합니까? 나는 progressbar가 audiotrack 클래스와 같은 스트리밍과 잘 작동하기 전에 읽었습니다. 어떤 아이디어, 감사합니다 – turtleboy
@turtleboy 나는 당신이 옳다고 생각하는데, 빠른 구글에서 보면 AudioTrack # write()가 버퍼에 데이터를 가지고있는 동안 블록하는 것처럼 보인다. –
@ dave.c 멋지다, 내가 들여다 볼 수있는 제안이있어? – turtleboy