Android线程错误 - 无法在未调用Looper.prepare()的线程内创建处理程序

时间:2014-08-06 02:06:43

标签: java android multithreading

我想让一个计时器在一个单独的线程中运行。

我在onCreate函数之前有以下声明:

TimerTask scanTask;
Timer t = new Timer();

然后在onCreate中的以下代码:

Runnable runnable = new Runnable() {
    @Override
    public void run() {
        scanTask = new TimerTask() {
            @Override
            public void run() {
                System.out.println("timer test");
            }
        };

        t.schedule(scanTask, 0, 5000);

        CountDownTimer waitTimer;
        waitTimer = new CountDownTimer(20000,300) {
            @Override
            public void onTick(long l) {
            }
            @Override
            public void onFinish() {
                t.cancel();
                System.out.println("Timer stopped");
            }
        }.start();
    }
}; 

Thread periodic_scan = new Thread(runnable);
periodic_scan.start();

然而,当我运行应用程序时,它会崩溃并给我错误: java.lang.RuntimeException:无法在未调用Looper.prepare()的线程内创建处理程序

我不确定我完全理解为什么会出现这种错误。它与UI线程有关吗?另外,我不确定我试图实现这个的方式是否正确。这是我第一次尝试处理Android中的线程。

3 个答案:

答案 0 :(得分:1)

你可以使用像

这样的HandlerThread
HandlerThread handlerThread = new HandlerThread("name");

handlerThread.start();

Handler threadHandler = new Handler(handlerThread.getLooper(),new Callback() {
    public boolean handleMessage(Message msg) {

    return true;  
 }
});

答案 1 :(得分:1)

我最后更改了一些代码并决定使用Thread类:

class TimerThread extends Thread {

    TimerTask scanTask;
    Timer t = new Timer();

    @Override
    public void run() {
        Looper.prepare();
        scanTask = new TimerTask() {
            public void run() {
                System.out.println("timer test");
            }
        };

        t.schedule(scanTask, 0, 5000);

        CountDownTimer waitTimer;
        waitTimer = new CountDownTimer(20000,300) {
            @Override
            public void onTick(long l) {

            }

            @Override
            public void onFinish() {
                t.cancel();
                System.out.println("Timer stopped");
            }
        }.start();

        Looper.loop();
    }
}

onCreate我使用了以下内容:

new TimerThread().start();

程序现在可以正常运行,但是现在唯一的问题是,在UI呈现到屏幕之前程序加载时会有明显的2-3秒延迟。

如果我使用的计时器功能在一个单独的线程上运行,我不确定为什么会发生这种情况,除非我在这里错过了一些内容......

答案 2 :(得分:0)

如果你创建一个处理程序(或你调用的任何类创建一个处理程序),它需要在一个有一个Looper的Thread中,并调用了Looper.prepare()。 TimerTask或CountDownTimer都是这样做的。如何解决它取决于您希望将事件发布到的位置。如果你想在UI线程上使用它们,则必须在UI线程上创建处理程序。如果你想在这个线程上使用它们,那么你需要在某个时候调用Looper.prepare和Looper.loop。

UI线程已经有一个looper(框架为你启动它)所以它总是可以在那里制作处理程序。