Search code examples
androidmultithreadingperformanceandroid-handlerthread

Stop HandlerThread which has a blocking call in it


I am making network request over TCP/IP and listening to the response on a separate thread. Each time I make a network call, I want to stop previous thread which is listening to response and make a new one.

Unfortunately, older HandlerThread is not getting terminated before starting the new one.

            if (mHandler != null) {
                mHandler.getLooper().quit();
            }
            if (mHandlerThread != null) {
                mHandlerThread.interrupt();
                mHandlerThread.quit();
            }
            mHandlerThread = new HandlerThread("socket-reader-thread");
            mHandlerThread.start();
            mHandler = new Handler(mHandlerThread.getLooper());
            mHandler.post(() -> {
                try {
                    String line;
                    while ((line = mBufferedReader.readLine()) != null) // BLOCKING CALL
                    {
                        ...
                    }
                    mBufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });

Is there a way to terminate these HandlerThreads?

Threads not getting terminated and piling


Solution

  • mHandlerThread.quit(); this line of code will just quit the handler thread's looper, this doesn't mean it terminates the thread immediately, because you post a message which executes while loop. If the message while loop not stop, the mHandlerThread will not stop forever. so you can change your code like this:

    mHandler.post(() -> {
        try {
            String line;
            while (!mHandlerThread.isInterrupted && (line = mBufferedReader.readLine()) != null)
            {
                ...
            }
            mBufferedReader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    });
    

    just add !mHandlerThread.isInterrupted() as a combined while loop condition.

    BTW, you don't need call:
    if (mHandler != null) { mHandler.getLooper().quit(); } but mHandlerThread.interrupt(); is necessary!