美文网首页
View.post(Runnable)

View.post(Runnable)

作者: 我的阿福 | 来源:发表于2020-06-11 17:26 被阅读0次

View的post(Runnable),Runnable的run为什么可以用来获取View的宽高?

先看post方法源码,很短:

    public boolean post(Runnable action) {
        final AttachInfo attachInfo = mAttachInfo;
        if (attachInfo != null) {
            return attachInfo.mHandler.post(action);
        }

        // Postpone the runnable until we know on which thread it needs to run.
        // Assume that the runnable will be successfully placed after attach.
        getRunQueue().post(action);
        return true;
    }

1.先看AttachInfo是什么,只看注释:

  /**
     * A set of information given to a view when it is attached to its parent
     * window.
     */
    final static class AttachInfo {
        interface Callbacks {
            void playSoundEffect(int effectId);
            boolean performHapticFeedback(int effectId, boolean always);
        }

说的很明白,当view添加到父视图时给view的一系列信息。

2.所以,再看post方法, if (attachInfo != null)说明已经添加到父视图了,已经初始化好了,这时候将Runnable投递到相应消息队列执行的时候,因为view已经初始化好,所以能获取到宽高。

3.还是post方法,如果,attachInfo 等于null,那么 getRunQueue().post(action);看一下

/**
 * Class used to enqueue pending work from Views when no Handler is attached.
 *
 * @hide Exposed for test framework only.
 */
public class HandlerActionQueue {
    private HandlerAction[] mActions;
    private int mCount;

    public void post(Runnable action) {
        postDelayed(action, 0);
    }

注释中,说明是在view未添加到父视图时对Runnable的排队处理,同时,在View的

 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    void dispatchAttachedToWindow(AttachInfo info, int visibility) {
        mAttachInfo = info;
      //...
        // Transfer all pending runnables.
        if (mRunQueue != null) {
            mRunQueue.executeActions(info.mHandler);
            mRunQueue = null;
        }

中可以看到,在被添加的时候,会再次取出排队的Runnable执行。言下之意,view在没有初始化的时候,会将受到的Runnable保存下来,当初始化成功后再取出来执行,所以也能获取到正确的宽高。

相关文章

网友评论

      本文标题:View.post(Runnable)

      本文链接:https://www.haomeiwen.com/subject/mhzbtktx.html