将Runnable发布到UI线程是否可以保证布局在运行时完成?

时间:2014-02-21 14:32:34

标签: android multithreading android-layout

第一件事!我了解ViewTreeObserver.onGlobalLayoutListener

让我问这个问题的是Android开发者文档网站上的以下通知:

  

以下代码段执行以下操作:

     
      
  • 获取父视图并在UI线程上发布Runnable。 这可确保父母在调用之前布置其子项   getHitRect()方法。 getHitRect()方法获取子命中   父母坐标中的矩形(可触摸区域)。
  •   

代码段本身是:

parentView.post(new Runnable() {
            // Post in the parent's message queue to make sure the parent
            // lays out its children before you call getHitRect()
            @Override
            public void run() {
               /// do UI stuff
            }
});

(您可以查看full article

这是错误的陈述还是真的? 我问,因为与使用ViewTreeObserver进行所有的register-listener / handle-event / unregister-listener舞蹈相比,发布runnable似乎更容易,更方便:)

更新:为整个主题带来清晰度的另一个问题: 如果所有这些都很好并且实际上可以发布Runnable而不是使用全局布局侦听器,那么为什么我们有这个ViewTreeObserver.onGlobalLayoutListener机制呢?什么时候使用它而不是发布Runnable更好,这种方法有什么区别?

1 个答案:

答案 0 :(得分:34)

我也喜欢这个问题。它迫使我再次深入挖掘Android源代码。我相信这是有效的,因为在post()之后调用了setContentView()

方法setContentView()最终会调用顶视图的ViewGroup.addView(),而addView()调用始终会触发requestLayout()。反过来,requestLayout()将任务发布到稍后要执行的主线程。此任务将在视图层次结构上执行度量和布局。现在,如果您发布另一个任务,它将在布局任务之后被放入队列中,因此,在测量和布局发生后始终执行。因此,您将始终拥有有效的尺寸。