Bootstrap

Handler.post 与 View.post 区别

Android  两个线程 UI线程和非UI线程。而Handler是非UI线程向UI线程传递消息的桥梁。

相同

在与UI线程的通信上,Handler与View,其实最终都做了同样的事情。就是将消息传递在UI线程

的消息队列里,执行一些处理操作。

不同

View.post方法想在非UI线程有效工作。如该方法的注释所说,必须保证该View已经被添加至窗口。

View.post()获取View宽高

public boolean post(Runnable action) {    
  final AttachInfo attachInfo = mAttachInfo;
  if (attachInfo != null) {       
  return attachInfo.mHandler.post(action);
  }    
// Assume that post will succeed later       
  ViewRootImpl.getRunQueue().post(action); 
  return true;
}
private void show(){
  if(myView.getVisibility()==View.GONE){
     myView.setVisibility(View.VISIBLE);
  }
     myView.post(new Runnable() {
            @Override
            public void run() {
                //对view执行动画
            }
        });
  }

意思是将任务交由attachInfo中的Handler处理,保证在UI线程执行。从本质上说,它还是依赖于以Handler、Looper、MessageQueue、Message为基础的异步消息处理机制。相对于新建Handler进行处理更加便捷。因为attachInfo中的Handler其实是由该View的ViewRootImpl提供的,所以post方法相当于把这个事件添加到了UI 事件队列中。下面举一个常用的例子,比如在onCreate方法中获取某个view的宽高,而直接View#getWidth获取到的值是0。要知道View显示到界面上需要经历onMeasure、onLayout和onDraw三个过程,而View的宽高是在onLayout阶段才能最终确定的,而在Activity#onCreate中并不能保证View已经执行到了onLayout方法,也就是说Activity的声明周期与View的绘制流程并不是一一绑定。那为什么调用post方法就能起作用呢?首先MessageQueue是按顺序处理消息的,而在setContentView()后队列中会包含一条询问是否完成布局的消息,而我们的任务通过View#post方法被添加到队列尾部,保证了在layout结束以后才执行。

;