Runnable在哪个线程上运行?

7

我希望每100毫秒更新UI。在StackOverflow上搜索后,我发现可以使用RunnableHandler实现,如下所示:

final Handler handler = new Handler();
Runnable runnable = new Runnable() {
    @Override
    public void run() {
        //update UI here

        handler.postDelayed(this, 100);
    }
};
runnable.run();

它有效!但我有一些问题:

  1. 这个Runnable在哪个线程运行?MainThread还是另一个线程?这里是关于postDelay的文档 enter image description here

Handler附加在MainThread上,那么Runnable是在MainThread上运行吗?

  1. 如果Runnable在MainThread上运行,为什么需要Handler?根据我的了解,Handler用于在两个线程之间发送消息。
3个回答

7
这个Runnable运行在哪个线程上?
Runnable runnable = new Runnable() {
    @Override
    public void run() {
        //update UI here

        handler.postDelayed(this, 100);
    }
};
runnable.run()

这个Runnable在当前线程上运行,即调用此代码的线程。它不会神奇地创建或构成另一个线程。Runnable.run()只是一个方法调用。

Handler在任何线程中运行时,此线程的后续执行基本上什么也不做,除了重新安排自己。很难相信这是解决任何问题的方法。


1
Handler被附加到主线程,那么Runnable在主线程上运行吗?根据 Handler文档:每个Handler实例都与单个线程及其消息队列相关联。当您创建新的Handler时,它绑定到正在创建它的线程/消息队列--从那时起,它将向该消息队列传递消息和可运行项,并在它们从消息队列出来时执行它们。如果要在不同线程上运行您的Runnable,可以使用 HandlerThread。相关帖子:为什么在Android中使用HandlerThread。如果Runnable在主线程上运行,为什么需要Handler?根据我的了解,Handler用于在两个线程之间发送消息。Handler有两个主要用途:
  1. 安排消息和可运行对象在未来某个时间点执行
  2. 将操作加入到与您自己不同的线程上执行。

如果只使用MainThread,则Handler可用于在将来某个时间点发送消息。如果使用不同的线程,则Handler可用于线程间通信。


1
在你的例子中,Runnable 在 UI 线程上运行。
如果你希望你的 Handler 和它所有的 Runnable 在不同的线程上运行,你需要为它分配一个新的 HandlerThreadLooper
final HandlerThread handlerThread = new HandlerThread(MY_THREAD_ID);
handlerThread.start();
final Handler handler = new Handler(handlerThread.getLooper());

您可以通过postDelayed(Runnable, long)传递Runnable实例。
Runnable r = new Runnable() {
    @Override public void run() {
        handler.postDelayed(this, 2000);
    }   
};

handler.postDelayed(r, 0);

不是第一次。 - user207421
@EJP的意思是第一次不要调用postDelayed吗? - payloc91
runnable.run() 首先由当前线程调用。下一次及以后,它将由 Handler 调用,而不是第一次。 - user207421
@pskink的陈述“在你的例子中,Runnable在UI线程上运行”以及我的评论都是指向OP的代码,这才是问题实际关注的内容。 - user207421
@EJP 第一个Runnable执行是由Handler调用的。从一开始,您就在单独的线程上运行,... - payloc91
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接