onResume中度量宽高是否可以?
不确定,需要看onResume在什么时候执行。
viewRootImpl需要在执行了requestLayout()之后才会执行onResume方法;
而没用执行requestLayout()方法的话就不会调用WindowManager的updateViewLayout()方法,就不会继续执行ViewRootImpl中的setLayoutParams、scheduleTraversals、doTraversals以及Session的relayout、WMS中的relayoutWindow方法。没有这套流程的方法就不会有度量控件宽高的执行,因此onResume中获取不到宽高。
onResume方法中通过new Handler().post()可不可以?
不可以。view还没有onMeasure()
setView–》requestLayout–》checkThread–》scheduleTraversals-》
scheduleTraversals中执行了mHandler.getLooper().getQueue().postSyncBarrier();
UI的刷新也是一个个MSG,UI的刷新是在主线程进行,而主线程队列可能堆积过多的MSG;在UI队列中为了保障UI刷新的MSG准时刷新,引入了消息屏障机制
屏障消息没有target。
private int postSyncBarrier(long when){
synchronized (this){
final int token = mNextBarrierToken++;
final Message msg = Message.obtain();
msg.markInUse();
msg.when = when;
msg.argl = token;
Message prev = null;
Message p = mMessages;
if (when != 0){
while (p != null && p.when <= when){
prev = p;
p = p.next;
}
}
if (prev != null){
msg.next = p;
prev.next = msg;
}else {
msg.next = p;
mMessages = msg;
}
return token;
}
}
//no target 优先执行
synchronized(this){
Message prevMsg = null;
Message msg = mMessage;
if(msg != null && msg.target == null){
do{
prevMsg = msg;
msg = msg.next;
}while(msg != null && !msg.isAsynchronous());
}
if(msg != null){
//do ......
}
}
而new Handler().post()方法在执行时屏障消息还没有执行,还没有执行requestLayout,也还没有执行scheduleTraversals,ui的屏障消息还没有执行,因此UI还没有刷新。
new Handler().postDelayed(,17);应该就能拿到宽高。
线程中view.setText一定会报错吗?
在onCreate中的新建子线程,view.setText()只是将内容存储到了view,都还没有执行addVIew操作更不会有UI刷新操作,因此不会报错,也不会有异常;在onResume中执行也不会出错,同理。如果在其他地方执行,已经进行了UI的刷新操作。如果再次进行子线程设置text的操作,WMS会检测到就会报错。
view的绘制过程都是用的同一个Canvas吗?
vieRootImpl中有preformDraw,在其中调用Draw函数,在该函数中调用drawSoftware函数,在这个函数中会调用canvas = mSurface.lockCanvas(dirty); 再调用mView.draw(canvas),然后再调用view类中的draw。
该draw()函数会先执行drawBackground(canvas)方法,然后执行onDraw(canvas)方法,然后执行dispatchDraw(canvas)将canvas分发给孩子。因此是用的同一个canvas
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KL7qJkqh-1638964830173)(C:\Users\wangshuo\AppData\Roaming\Typora\typora-user-images\image-20211208195831454.png)]
patchDraw(canvas)将canvas分发给孩子。因此是用的同一个canvas