View中的 postInvalidate 和 invalidate 的区别
程序员文章站
2022-07-11 08:27:19
...
自定义绘制 View 的时候,需要刷新界面。
其中有两个刷新的方法,postInvalidate 和 invalidate。两者长的很像,我们如何区分来开呢?
下面我们来看看源码:
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);
}
注释里面写道,一定要在 UI线程中调用,如果想要在非 UI 线程中调用,可以使用 postInvalidate()方法。
继续查看~~~
/**
* 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.
*/
void invalidate(boolean invalidateCache) {
invalidateInternal(0, 0, mRight - mLeft, mBottom - mTop, invalidateCache, true);
}
这时候需要工作的实际发生地出现了
- - - - - - - - - - - - - - - - - - - - - 我是华丽丽的分割线- - - - - - - - - - - - - - - - - - - - -
接下来看一下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);
}
注释中也有写到,是要在非 UI线程中使用。并且指定了延迟的时间为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);
}
final class ViewRootHandler extends Handler {
@Override
public String getMessageName(Message message) {
//省略。。。
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_INVALIDATE:
((View) msg.obj).invalidate();
break;
//省略。。。
}
}
看到此处可以看出来 postInvalidate()方法中其实是使用了Handler 机制的,实际最后也调用了 invalidate()方法。推荐阅读
-
Android MotionEvent中getX()和getRawX()的区别实例详解
-
oracle中left join和right join的区别浅谈
-
详解Node.js中path模块的resolve()和join()方法的区别
-
Python中__init__和__new__的区别详解
-
详解MySQL中DROP,TRUNCATE 和DELETE的区别实现mysql从零开始
-
SQL中distinct 和 row_number() over() 的区别及用法
-
Android中dip、dp、sp、pt和px的区别详解
-
H5 canvas中width、height和style的宽高区别详解
-
Android中父View和子view的点击事件处理问题探讨
-
Oracle中的Connect/session和process的区别及关系介绍