何时使用handler.post()和何时使用new Thread()?

75
我想知道何时应该使用handler.post(runnable);,何时应该使用new Thread(runnable).start();
在Handler的开发者文档中提到:

将Runnable r添加到消息队列中。该runnable将在此处理程序附加的线程上运行。

这是否意味着如果我在Activity类的onCreate()方法中编写以下代码:
Handler handler = new Handler();
handler.post(runnable);

然后,runnable 将在单独的线程或 Activity 的线程中调用?

1
不要使用new Thread(runnable).start(),否则可能会耗尽VM堆栈内存。你应该使用Executors并存储对它的引用(不要为每个调用创建一个新的执行器,这将导致在后台线程中运行) - EpicPandaForce
4个回答

106
您应该在想要在UI线程上执行操作时使用Handler.post()
假设您想在回调中更改TextView的文本。因为回调不在UI线程上运行,所以您应该使用Handler.post()
在Android中,与许多其他UI框架一样,只能从UI线程修改UI元素(小部件)。
还请注意,“UI线程”和“主线程”这些术语经常可以互换使用。
编辑:一个长时间运行的任务的例子:
mHandler = new Handler();

new Thread(new Runnable() {
  @Override
  public void run () {
    // Perform long-running task here
    // (like audio buffering).
    // You may want to update a progress
    // bar every second, so use a handler:
    mHandler.post(new Runnable() {
     @Override
     public void run () {
       // make operation on the UI - for example
       // on a progress bar.
     }
    });
  }
}).start();

当然,如果您要执行的任务确实很长,并且有可能用户在此期间切换到其他应用程序,您应该考虑使用Service


但是,如果我想从互联网缓冲音频流,我应该通过handler.post还是新线程来实现? - reiley
1
真的取决于您的要求。我会考虑使用新线程或服务。我会在一秒钟内更新答案并提供示例。 - kamituel
4
“解释在很多层面上都是错误的。- T.Dimitrov” 真的吗?绝对没有依据且毫无用处的评论。你的证据在哪里? - Stanly T
3
@T.Dimitrov,您可能需要更明确地说明这里的解释到底有什么问题,否则其他人将不知道您的意思。 - EpicPandaForce

37

针对你的具体问题:

如果我在Activity类的onCreate方法中编写以下代码:

Handler handler = new Handler() hanlder.post(runnable); 那么,runnable会在单独的线程上调用还是在Activity的线程上调用?

不会在单独的线程上调用,Runnable将在主线程上调用。 Handler仅用于向其所附加的线程(即创建它的线程)发布消息。它本身不会创建线程。 在你的例子中,你在主线程中创建了一个Handler(即Activity.OnCreate()被调用的地方),因此在这样的Handler上发布的任何消息都将在主线程上运行。


6
正确答案并不总是被选为最佳答案。谢谢。 - Natan Lotério
1
你完全改变了我的应用程序的性能!!从handler到thread的转换让我的应用程序飞起来了!非常感谢你! - hzitoun

12

例子被篡改了:

mHandler = new Handler();
new Thread(new Runnable(){
  @Override
  public void run () {
    mHandler.post(new Runnable() {
     @Override
     public void run () {
       mUiView.setX(x);
     }
    });
  }
}).start();

或者,您可以跳过处理程序并直接在视图上使用post方法:

new Thread(new Runnable(){
  @Override
  public void run () {
    mUiView.post(new Runnable() {
     @Override
     public void run () {
       mUiView.setX(x);
     }
    });
  }
}).start();

这是一篇很好的文章,概述了差异:什么是 POST 方法?


8

当您想要将代码(通常来自后台线程) 发布主线程中时,请使用handler.post()。是的,就像您向某人发送信件一样,进行POST操作。借助handler的帮助,代码将尽快执行,即几乎立即执行。


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