Java – Handler stuck UI when cycling through runnable tasks [android]

Handler stuck UI when cycling through runnable tasks [android]… here is a solution to the problem.

Handler stuck UI when cycling through runnable tasks [android]

I’m going to repeat – – – … Wait a minute.
When its energy reaches a certain threshold and is played, the recording (for a few seconds) stops. After playback, start a new recording. So I have to use the buffer to monitor the energy and start a new recording after the playback time is calculated. My pseudocode (in its simplest form) looks like this:

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);
    };
}

This is triggered by the start and stop buttons, as shown below

    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);
        }
    });

The problem is that when recording or playing audio, no button works, I have to wait until it finishes recording. How do I prevent stuck recording? Is it just because of the whileloop? Please help..!

If I run it as follows, no error is reported.

Thread t = new Thread(timedTask);
t.start();

This is just ok once, but then it also gets stuck in the UI when the handler is delayed.

Solution

The handler posts the runnable task to a looper in a thread. It does not create a new thread on its own to run the runnable asynchronously.

When you create a handler by calling the constructor new Handler(), the handler gets the looper for the current thread that calls the constructor by default. Because you called new Handler() on the UI thread, any runnable objects provided for the handler’s post command are added to the UI thread.

You need to create a new thread and get its looper by doing the following

HandlerThread readThread = new HandlerThread("");
readThread.start();
myHandler = new Handler(readThread.getLooper());

A handlerThread is a thread that automatically sets up a looper for you to use.

Of course, you also need to quit the thread when you don’t need it

readThread.quit();

Related Problems and Solutions