Handler系列五:Handler.post和View.post

53 阅读2分钟

Handler.postView.post 都是将Runnable对象安排到主线程(UI线程)的消息队列中执行。

Handler.post

  • 定义Handler 是线程间通信的工具,在不同的线程之间发送和处理消息或Runnable对象。
  • 用途:主要用于跨线程通信,特别是在非UI线程(如后台线程)中执行完任务后,需要将结果或更新发送到UI线程。
  • 特点
    • 需要显式创建Handler实例(除非已有)。
    • 通过post(Runnable r)方法将Runnable对象添加到与Handler关联的消息队列中,默认是主线程的消息队列。
    • 提供更多配置选项和方法,如sendMessagesendEmptyMessage等,因此更灵活。

View.post

  • 定义View类中的post(Runnable r)方法提供了一种便捷方式,将Runnable对象安排到UI线程的消息队列中执行。
  • 用途:用于在UI线程中延迟或异步地更新UI元素,无需显式创建Handler对象。
  • 特点
    • 自动使用与该View关联的Handler(如果存在)。
    • 简化了在UI线程中执行Runnable对象的步骤。
    • 适用于简单的UI更新任务,代码更简洁。

主线程和子线程使用Handler的区别

  • UI线程(主线程)中的Handler
    • 通常用于在该线程上执行耗时较短的任务或更新UI元素。
    • 自动关联到UI线程的Looper,无需手动设置。
    • 发送延迟消息或Runnable对象到UI线程,以在未来某个时间点更新UI。
    • 响应子线程发送的消息或Runnable对象,执行UI更新操作。
    // 在UI线程中创建Handler实例  
    Handler handler = new Handler() {  
        @Override  
        public void handleMessage(Message msg) {  
            // 处理消息  
            super.handleMessage(msg);  
        }  
    };  
      
    // 使用handler发送消息  
    Message message = Message.obtain();  
    // 设置消息内容(如果需要的话)  
    // message.what = ...;  
    // handler.sendMessage(message);  
      
    // 或者,直接发送一个Runnable到Handler处理  
    handler.post(new Runnable() {  
        @Override  
        public void run() {  
            // 在这里执行UI更新等操作  
        }  
    });
  • 子线程中的Handler
    • 需要显式创建并启动Looper,然后将Handler与该Looper关联。
    • 主要用于在该子线程中处理消息或执行Runnable对象。
    • 发送延迟消息或Runnable对象到子线程,以在未来某个时间点执行。
    • 在子线程内部处理来自其他线程的消息或Runnable对象。
    new Thread(new Runnable() {  
        @Override  
        public void run() {  
            // 在这个线程中创建Looper  
            Looper.prepare();  
      
            // 创建Handler实例  
            Handler handler = new Handler() {  
                @Override  
                public void handleMessage(Message msg) {  
                    // 处理消息  
                }  
            };  
      
            // 使用handler发送消息(这里只是示例,实际发送应该在其他地方)  
      
            // 保持线程运行,以便Looper可以持续接收消息  
            Looper.loop();  
        }  
    }).start();

总结

  • Handler.postView.post 都能将Runnable对象安排到UI线程执行, 但Handler.post更灵活,适用于跨线程通信; View.post更简洁,适用于UI线程内的异步更新。
  • 在UI线程中使用Handler,通常是为了延迟执行UI更新或响应子线程消息; 在子线程中使用Handler,需要创建并启动Looper,用于处理该线程内部的任务调度。