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

dim*_*suz 37 multithreading android 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
            }
});
Run Code Online (Sandbox Code Playgroud)

(你可以看一整篇文章)

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

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

ser*_*nka 37

我也喜欢这个问题.它迫使我再次深入挖掘Android源代码.我相信这是有效的,因为post()被召唤setContentView().

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

  • 我相信,如果你添加一个视图,那么你可以用发布的runnable替换一次性监听器.但是如果您需要收到有关每个布局的通知,或者您需要其他类型的事件,则需要此监听器. (2认同)