刷新界面之invalidate()与postInvalidate()
刷新View的界面,有两种方法:invalidate()和postInvalidate(),那么他们又有什么区别和联系呢?
invalidate():一般用于更新UI线程里的View界面
postInvalidate():用于更新非UI线程的View界面
难道invalidate(),只能用于UI线程吗?在工作者线程(非UI线程)就不能用吗?非也,如果大家了解Handler的话,就知道我们完全可以利用Handler来通知UI,实现就是Handler+invalidate()。其实,前面已经说了,既然在非UI线程,我们完全可以只使用postInvalidate()就行,简单方便。
其实,大家如果参看源码的话,不难发现postInvalidate()的内部实现就是我们提到的Handler+invalidate(),
public void postInvalidate(int left, int top, int right, int bottom) {
postInvalidateDelayed(0, left, top, right, bottom);
}
跟进postInvalidateDelayed方法里看看
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);
}
}
再跟进dispatchInvalidateDelayed方法里看看
public void dispatchInvalidateDelayed(View view, long delayMilliseconds) {
Message msg = mHandler.obtainMessage(MSG_INVALIDATE, view);
mHandler.sendMessageDelayed(msg, delayMilliseconds);
}
final ViewRootHandler mHandler = new ViewRootHandler();
final class ViewRootHandler extends Handler
哈哈,终于看到了我们的Handler,mHandler是继承于Handler的对象,具体看看ViewRootHandler的部分核心代码handleMessage(Message msg)
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_INVALIDATE:
<span style="color:#ff0000;">((View) msg.obj).invalidate();</span>
break;
此处省略很多代码...
}
跟踪了半天,postInvalidate()是不是最终还是调用了invalidate()?其实postInvalidate()的出现就是简化我们在非UI线程更新view的步骤,我们不再需要自己实现有一个Handler,然后在Handler的handleMessage(Message msg)里调用invalidate(),而是只需要一句postInvalidate(),一句代码搞定!so easy,妈妈再也不用担心我的学习。