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方法
网友评论