美文网首页
postInvalidate和Invalidate的区别(源码分

postInvalidate和Invalidate的区别(源码分

作者: 如愿以偿丶 | 来源:发表于2019-09-29 22:03 被阅读0次

1.Invalidate

我们从源码中去简单看一下View的invalidate()的方法:

    /**
     * Invalidate the whole view. If the view is visible,
     * {@link #onDraw(android.graphics.Canvas)} will be called at some point in
     * the future.
     * <p>
     * This must be called from a UI thread. To call from a non-UI thread, call
     * {@link #postInvalidate()}.
     */
    public void invalidate() {
        invalidate(true);
    }

通过方法注释可知,Invalidate会去刷下我们的View,当我们的View为可见性为visible时,View的onDraw方法就会被调用,另外该方法只能在UI线程中被调用。

    /**
     * This is where the invalidate() work actually happens. A full invalidate()
     * causes the drawing cache to be invalidated, but this function can be
     * called with invalidateCache set to false to skip that invalidation step
     * for cases that do not need it (for example, a component that remains at
     * the same dimensions with the same content).
     *
     * @param invalidateCache Whether the drawing cache for this view should be
     *            invalidated as well. This is usually true for a full
     *            invalidate, but may be set to false if the View's contents or
     *            dimensions have not changed.
     * @hide
     */
    public void invalidate(boolean invalidateCache) {
        invalidateInternal(0, 0, mRight - mLeft, mBottom - mTop, invalidateCache, true);
    }

我们看到,invalidate()方法中是调用invalidate(true),参数true的意思是需要刷新整体,从注释可知我们可以通传传入参数false使方法无效,所以当View的内容和大小没有任何变化时我们可以传入false。


2.postInvalidate

我们从源码中去简单看一下View的postInvalidate()的方法:

    /**
     * <p>Cause an invalidate to happen on a subsequent cycle through the event loop.
     * Use this to invalidate the View from a non-UI thread.</p>
     *
     * <p>This method can be invoked from outside of the UI thread
     * only when this View is attached to a window.</p>
     *
     * @see #invalidate()
     * @see #postInvalidateDelayed(long)
     */
    public void postInvalidate() {
        postInvalidateDelayed(0);
    }


    public void postInvalidateDelayed(long delayMilliseconds) {
        // We try only with the AttachInfo because there's no point in invalidating
        // if we are not attached to our window
        final AttachInfo attachInfo = mAttachInfo;
        if (attachInfo != null) {
            attachInfo.mViewRootImpl.dispatchInvalidateDelayed(this, delayMilliseconds);
        }
    }

    /**
    * ViewRootImapl中的方法
    */
    public void dispatchInvalidateDelayed(View view, long delayMilliseconds) {
        //1.通过mHandler.obtainMessage从Message池中获取,如果没有就会new Message()
        Message msg = mHandler.obtainMessage(MSG_INVALIDATE, view);
        //2.handler发送消息
        mHandler.sendMessageDelayed(msg, delayMilliseconds);
    }


    //Message的处理,通过Message池中获取,没有则new Message();
    public final Message obtainMessage(int what, Object obj){
       return Message.obtain(this, what, obj);
     }

    public static Message obtain(Handler h, int what, Object obj) {
            Message m = obtain();
            m.target = h;
            m.what = what;
            m.obj = obj;
    
            return m;
    }
    
     public static Message obtain() {
        synchronized (sPoolSync) {
            if (sPool != null) {
                Message m = sPool;
                sPool = m.next;
                m.next = null;
                m.flags = 0; // clear in-use flag
                sPoolSize--;
                return m;
            }
        }
        return new Message();
    }

通过方法注释可知,postInvalidate可以在非UI线程中去调用刷新UI的

    final ViewRootHandler mHandler = new ViewRootHandler();
    
    final class ViewRootHandler extends Handler {
            @Override
            public String getMessageName(Message message) {
                switch (message.what) {
                    case MSG_INVALIDATE:
                        return "MSG_INVALIDATE";
                }
                return super.getMessageName(message);
            }

       @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_INVALIDATE:
                    //调用了View的invalidate方法
                    ((View) msg.obj).invalidate();
                    break;
                case MSG_INVALIDATE_RECT:
                    final View.AttachInfo.InvalidateInfo info =
                            (View.AttachInfo.InvalidateInfo) msg.obj;
                    info.target.invalidate(info.left, info.top, info.right, info.bottom);
                    info.recycle();
                    break;
                    ...
            }
        }
    }

通过Handler发送消息,最终还是调用了View的invalidate方法

相关文章

网友评论

      本文标题:postInvalidate和Invalidate的区别(源码分

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