HandlerThread throws RuntimeException Only one Looper may be created per thread

391 Views Asked by At

This crash report only contains system trace, because it happens in the HandlerThread:

java.lang.RuntimeException: Only one Looper may be created per thread

at android.os.Looper.prepare(Looper.java:107)

at android.os.Looper.prepare(Looper.java:102)

at android.os.HandlerThread.run(HandlerThread.java:54)

Seems the looper's prepare is called already for the HandlerThread. I just don't understand why the HandlerThread's run entering again. It only shows the system's java stacktrace.

I tried calling the HandlerThread's start() method multiple times, it throwed java.lang.IllegalThreadStateException, not the RuntimeException.

So when HandlerThread throws such exception?

========================================================

The key code about the HandlerThread and Handler is below:

class MyDeviceFragment extends BaseFragment {
    private HandlerThread mWorkerThread = new HandlerThread(MyDeviceFragment .class.getName());
    private WorkerHandler mWorkerHandler;
    {
        if (mWorkerHandler == null) {
            mWorkerThread.start();
            mWorkerHandler = new WorkerHandler(mWorkerThread.getLooper());
        }
    }
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // xxxxx code
    }
    public void onDetach() {
        super.onDetach();
        if (mWorkerThread != null) {
            mWorkerThread.quit();
        }
    }

    private class WorkerHandler extends Handler {
        WorkerHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case MSG_XXXXX1:
                    synchronized (mLock) {
                        // CODE
                    }
                    break;
                case MSG_XXXXX2:
                    synchronized (mLock) {
                        // CODE
                    }
                    break;
            }
        }
    }
}

And using mWorkerHandler.sendEmptyMessage(MSG_XXX) to send message. The initialization of mWorkerThread is a little weird, written by third-party, but I don't think it could cause HandlerThread throwing the RuntimeException. Am i right?

1

There are 1 best solutions below

0
quan yang On

I think we can extends HandlerThread

@Override
public void run() {
    try {
        super.run();
    } catch (Exception e) {
        LogUtil.e(TAG, "run e =" + e);
    }
}

But I have no idea about reason.