美文网首页
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