onResume中是否可以度量宽高?

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
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值