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

ben*_*Heo 3 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);
    };
}
Run Code Online (Sandbox Code Playgroud)

这由启动和停止按钮触发,如下所示,

    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);
        }
    });
Run Code Online (Sandbox Code Playgroud)

问题是当音频正在录制或播放时,没有按钮正在工作,我必须等到它完成录制.如何防止冻结录音?是因为whileloop吗?请帮忙..!

如果我按如下方式运行,则没有错误.

Thread t = new Thread(timedTask);
t.start();
Run Code Online (Sandbox Code Playgroud)

这只是一次性的,但是当处理程序在延迟时间内执行时,它也冻结了UI.

Cur*_*vus 5

处理程序将可运行的任务发布到线程中的looper中.它不会自动创建一个新的线程,在该线程上异步运行runnables.

当您通过调用构造函数创建处理程序时new Handler(),处理程序将获取默认情况下从中调用构造函数的当前线程的循环器.因为您调用new Handler()了UI线程,所以给予处理程序的post命令的任何runnable都将被添加到UI线程中.

你需要创建一个新的线程并通过这样做来获得它的looper

HandlerThread readThread = new HandlerThread("");
readThread.start();
myHandler = new Handler(readThread.getLooper());
Run Code Online (Sandbox Code Playgroud)

HandlerThread是一个自动设置looper供您使用的线程.

当然,一旦您不需要它,您还需要退出该线程

readThread.quit();
Run Code Online (Sandbox Code Playgroud)

  • 我想投票,但我不能因为我的声誉低.我将在不久的将来回来投票!谢谢! (2认同)