简述View#post与Handler#post的区别 ?

参考回答:

View#post()Handler#post()都可以用来将任务添加到消息队列中,但它们的作用和使用场景有所不同。View#post()是将任务发布到当前View所在的UI线程的消息队列中,并且通常用来更新UI,而Handler#post()是将任务发布到指定的Handler对应的Looper的消息队列中,可以指定任务执行的线程。

详细讲解与拓展:

1. View#post()

  • 功能:将一个Runnable任务添加到当前View所在的UI线程的消息队列中,并等待系统在合适的时机执行该任务。
  • 使用场景View#post()通常用于需要在UI线程执行的任务,尤其是更新UI时。它可以确保任务在当前View的所属线程中运行,通常是主线程。

    示例

    myView.post(new Runnable() {
      @Override
      public void run() {
          // 在UI线程中执行更新UI的操作
          myView.setVisibility(View.VISIBLE);
      }
    });
    
    Java
  • 执行时机post()方法将任务加入到当前ViewUI线程的消息队列中,任务会在下一帧绘制前执行。也就是说,任务会在当前事件循环结束之后执行。

2. Handler#post()

  • 功能Handler#post()将一个Runnable任务添加到与Handler关联的Looper的消息队列中。Handler会根据其所绑定的Looper来决定任务在哪个线程执行。
  • 使用场景Handler#post()可以用于任何线程,只要该Handler与指定的Looper(主线程或子线程)关联。它通常用来在非UI线程中发送消息或任务,确保任务在指定的线程中执行。

    示例

    Handler handler = new Handler(Looper.getMainLooper());
    handler.post(new Runnable() {
      @Override
      public void run() {
          // 在UI线程中执行更新UI的操作
          myView.setVisibility(View.VISIBLE);
      }
    });
    
    Java

    这个示例中,Handler与主线程的Looper关联,因此任务会在主线程中执行。

  • 执行时机Handler#post()将任务添加到与Handler绑定的Looper的消息队列中,任务将在该Looper的事件循环中被处理。对于主线程的Handler,任务会在主线程执行。

3. 区别总结

  • 目标线程

    • View#post()始终将任务发送到UI线程,即当前View所在的线程。
    • Handler#post()将任务发送到与该Handler关联的Looper对应的线程,通常是主线程,但也可以是任何Handler所绑定的线程。
  • 灵活性
    • View#post()不需要指定线程,因为它默认将任务发送到UI线程
    • Handler#post()更为灵活,可以选择目标线程,通过指定Looper来控制任务执行在哪个线程。
  • 常见用途
    • View#post()适用于在UI线程中执行与View相关的更新操作。
    • Handler#post()适用于任何线程间的任务调度,特别是在子线程中更新UI或进行异步操作时。

总结:

View#post()Handler#post()都可以将任务添加到消息队列中,但它们的主要区别在于目标线程的不同。View#post()将任务发送到UI线程,通常用于更新UI;而Handler#post()允许更灵活的选择目标线程,它会将任务发送到与Handler关联的Looper的消息队列中。

发表评论

后才能评论