postInvalidate和invalidate的区别

来源:互联网 发布:linux系统如何重启 编辑:程序博客网 时间:2024/06/07 04:50

相同点:都是用来更新当前的View
不同点:invalide实在UI线程中刷新View,要想在非UI线程中刷新View,就要用postInvalidate,因为postInvalidate底层是使用了Handler

同时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);    }
/**     * <p>Cause an invalidate to happen on a subsequent cycle through the event     * loop. Waits for the specified amount of time.</p>     *     * <p>This method can be invoked from outside of the UI thread     * only when this View is attached to a window.</p>     *     * @param delayMilliseconds the duration in milliseconds to delay the     *         invalidation by     *     * @see #invalidate()     * @see #postInvalidate()     */    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);        }    }
 public void dispatchInvalidateDelayed(View view, long delayMilliseconds) {        Message msg = mHandler.obtainMessage(MSG_INVALIDATE, view);        mHandler.sendMessageDelayed(msg, delayMilliseconds);    }

requestLayout在什么时候用呢?

当view确定自身已经不再适合现有的区域时,该view本身调用这个方法要求parent view(父类的视图)重新调用他的onMeasure onLayout来重新设置自己位置。特别是当view的layoutparameter发生改变,并且它的值还没能应用到view上时,这时候适合调用这个方法

除此之外,二者还有点小区别。

调用invalidate时,它会检查上一次请求的UI重绘是否完成,如果没有完成的话,那么它就什么都不做。

void invalidateInternal(int l, int t, int r, int b, boolean invalidateCache,            boolean fullInvalidate) {            .....         //DRAWN和HAS_BOUNDS是否被设置为1,说明上一次请求执行的UI绘制已经完成,那么可以再次请求执行        if ((mPrivateFlags & (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)) == (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)                || (invalidateCache && (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID)                || (mPrivateFlags & PFLAG_INVALIDATED) != PFLAG_INVALIDATED                || (fullInvalidate && isOpaque() != mLastIsOpaque)) {                 ......                 final AttachInfo ai = mAttachInfo;                final ViewParent p = mParent;                final Rect damage = ai.mTmpInvalRect;                damage.set(l, t, r, b);                p.invalidateChild(this, damage);//TODO:这是invalidate执行的主体                .....        }    }

而postInvalidate则不会这样,它是向主线程发送个Message,然后handleMessage时,调用了invalidate()函数。

0 0
原创粉丝点击