在可运行任务中循环处理时,处理程序冻结UI [android]

时间:2015-02-19 00:46:07

标签: java android handler

我想重复 - - -...等等。 当能量达到某个阈值并重放时,记录(秒)停止。播放后,开始新录制。因此,我必须使用缓冲区监视能量,并在回放时间计算后开始新的记录。我的伪代码(最简化形式)如下所示:

...

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。

2 个答案:

答案 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());
        ...
    }
}