1

我有一个class扩展Thread如下 -

public class ThreadTest extends Thread {

    private Handler handler;
    private Runnable runnable;

    public ThreadTest(Runnable runnable, Handler handler) {

        this.handler = handler;
        this.runnable = runnable;
    }

    @Override
    public void run() {
        super.run();

        Message msg = handler.obtainMessage();
        msg.obj = "YUSSSSSS!";
        handler.sendMessage(msg);

        if (Looper.myLooper() != null) {
            Looper.myLooper().quit();
            Log.i("Looper", "has been quit");
        }

    }
}

现在,我想在looper这个线程上附加一个。根据我对Looper只有主线程的理解,looper默认情况下会附加到它。

我尝试像这样调用Looper.prepare()Looper.loop()形成ThreadTest类的构造函数-

public ThreadTest(Runnable runnable, Handler handler) {

        Looper.prepare();

        this.handler = handler;
        this.runnable = runnable;

        Looper.loop();
    }

但是,我java.lang.RuntimeException: Only one Looper may be created per threadLooper.prepare();.

虽然,如果我附上looperin Run(),我不会遇到任何问题。

我究竟做错了什么?

4

2 回答 2

0

每个线程都有一个弯针并且只有一个弯针,您需要在尝试将弯针添加到线程之前进行检查。

您还需要添加 if (Looper.myLooper() != null) {}构造函数。请记住,looper.myLooper() 如果您在线程构造函数中调用它,则只能获取主线程 Looper。因为那个时候新线程还没有构建。

于 2018-10-30T14:59:57.213 回答
0

当您调用Looper.prepare()构造函数时,实际上是通过调用其构造函数(您没有指定,但我猜是主线程)从创建对象的任何其他线程调用它,但该run()方法是从线程本身调用的。所以你应该附上你的looperin run()

run()要被调用,你必须调用Thread.start()并且没有保证run()会在你调用后立即被调用start(),所以如果你希望looper在调用构造函数后立即可用,你可以在构造函数中等待直到run()被调用,然后notify()等待线程在这样的构造函数中:

public class ThreadTest extends Thread
{
    public ThreadTest()
    {
        //init...

        //wait until thread has started
        waitForRun();
    }

    private void waitForRun()
    {
        try
        {
            synchronized (this)
            {
                start();
                wait();
            }
        }
        catch (InterruptedException ignored)
        {
            
        }
    }

    @Override
    public void run()
    {
        Looper.prepare();
        synchronized (this)
        {
            //notify the waiting thread in the constructor that this thread
            //has started and has a looper
            notifyAll();
        }

        //do stuff...

        Looper.loop();
    }
}
于 2021-06-08T06:07:39.867 回答