在线程的构造函数中调用Looper.prepare()会导致RunTimeException

时间:2017-09-26 16:57:53

标签: java android multithreading android-thread

我的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 thread处获得Looper.prepare();例外。

然而,如果我在looper附加Run(),我就不会遇到任何问题。

我做错了什么?

2 个答案:

答案 0 :(得分:0)

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

您还需要在构造函数中添加if (Looper.myLooper() != null) {}。 请记住,looper.myLooper()仅在线程构造函数中调用时才能获得主线程循环器。因为那时还没有构造新线程。

答案 1 :(得分:0)

当您在构造函数中调用 Looper.prepare() 时,它实际上是从通过调用其构造函数(您没有指定但我猜是主线程)创建对象的任何其他线程调用的,但是 {{ 1}} 方法是从线程本身调用的。因此,您应该在 run() 中附加您的 looper

要调用 run(),您必须调用 run() 并且不能保证在调用 Thread.start() 后会立即调用 run() 所以如果您想要start() 要在调用构造函数后立即可用,您可以在构造函数中等待直到调用 looper,然后 run() 构造函数中的等待线程像这样:

notify()