我想重复 - - -...等等。 当能量达到某个阈值并重放时,记录(秒)停止。播放后,开始新录制。因此,我必须使用缓冲区监视能量,并在回放时间计算后开始新的记录。我的伪代码(最简化形式)如下所示:
...
public class MainActivity extends Activity {
private Handler myHandler = new Handler();
....
private Runnable timedTask = new Runnable() {
public void run() {
audiorecorder = new AudioRecord(... initializes
audiorecorder.startRecording();
isRecording = true;
ElapsedTime = 0.0;
while(true) {
ReadByte = audiorecorder.read(buffer, 0, buffersize);
// Write ReadByte onto file (temp.pcm)
EnergyBuffer = <some averaged energy over a period (1 sec or so)>
if(EnergyBuffer > Threshold)
break;
ElapsedTime = ...
}
// audiorecorder.release, stop, and null
// play temp.pcm using AudioTrack
myHandler.postDelayed(timedTask, Elapsedtime);
};
}
,这由启动和停止按钮触发,如下所示,
StartButton.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
myHandler.post(timedTask);
}
});
StopButton.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
myHandler.removeCallbacks(timedTask);
}
});
问题是当音频正在录制或播放时,没有按钮正在工作,我必须等到它完成录制。如何防止冻结录音?是因为whileloop吗?请帮忙..!
如果我按如下方式运行,则没有错误。
Thread t = new Thread(timedTask);
t.start();
这只是一次性的,但是当处理程序在延迟时间内执行时,它也冻结了UI。
答案 0 :(得分:5)
处理程序将可运行的任务发布到线程中的looper中。它不会自动创建一个新的线程,在该线程上异步运行runnables。
当您通过调用构造函数new Handler()
创建处理程序时,处理程序将获取默认情况下从中调用构造函数的当前线程的循环器。由于您在UI线程上调用了new Handler()
,因此任何给予处理程序的post命令的runnable都将被添加到UI线程中。
你需要创建一个新的线程并通过
获得它的循环HandlerThread readThread = new HandlerThread("");
readThread.start();
myHandler = new Handler(readThread.getLooper());
HandlerThread是一个自动设置looper供你使用的线程。
当然,一旦你不需要它,你还需要退出该线程
readThread.quit();
答案 1 :(得分:1)
你是天才,工作就像一个魅力,这正是我工作了几天,非常感谢你! 以下是我的问题的答案:
public class MainActivity extends Activity {
private Handler myHandler;
....
private Runnable timedTask = new Runnable() {
public void run() {
audiorecorder = new AudioRecord(... initializes
audiorecorder.startRecording();
isRecording = true;
ElapsedTime = 0.0;
while(true) {
ReadByte = audiorecorder.read(buffer, 0, buffersize);
// Write ReadByte onto file (temp.pcm)
EnergyBuffer = <some averaged energy over a period (1 sec or so)>
if(EnergyBuffer > Threshold)
break;
ElapsedTime = ...
}
// audiorecorder.release, stop, and null
// play temp.pcm using AudioTrack
myHandler.postDelayed(timedTask, Elapsedtime);
};
....
protected void OnCreate(Bundle savedInstanceState) {
...
HandlerThread readThread = new HandlerThread("");
readThread.start();
myHandler = new Handler(readThread.getLooper());
...
}
}