Android开发面试:requestLayout() 这么问,面试者直呼:太细了!

那必定是因为之后的 layout() 方法没有得到执行,导致 PFLAG_FORCE_LAYOUT 无法被清除。

欲探究竟,接着往下看。

如果你知道 requestLayout() 调用是一个层级调用,那么恭喜你,你已经处于认知的第一层了。送你一张二层入场券。

第二层(VRI.requestLayout)

==================================================================================

我们来看看第一层讲到的 ViewRootImpl.requestLayout()。

//ViewRootImpl.java

@Override

public void requestLayout() {

if (!mHandlingLayoutInLayoutRequest) {

checkThread();

mLayoutRequested = true;

scheduleTraversals();

}

}

void scheduleTraversals() {

if (!mTraversalScheduled) {

mTraversalScheduled = true;

//1. 往主线程的Handler对应的MessageQueue发送一个同步屏障消息

mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();

//2. 将mTraversalRunnable保存到Choreographer中

mChoreographer.postCallback(

Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);

if (!mUnbufferedInputDispatch) {

scheduleConsumeBatchedInput();

}

notifyRendererOfFramePending();

pokeDrawLockIfNeeded();

}

}

该方法主要作用如下:

  1. 往主线程的 Handler 对应的 MessageQueue 发送一个同步屏障消息;

  2. 将 mTraversalRunnable 保存到 Choreographer 中;

此处有三个特别重要的知识点:

  1. mTraversalRunnable;

  2. MessageQueue 的同步屏障;

  3. Choreographer 机制;

mTraversalRunnable 相对比较简单,它的作用就是从 ViewRootImpl 从上往下执行 performMeasure()、performLayout()、performDraw()。

重点:它的执行时机是当 VSync 信号来到时,会往主线程的 Handler 对应的 MessageQueue 中发送一条异步消息,由于在 scheduleTraversals() 中给 MessageQueue 中发送过一条同步屏障消息,那么当执行到同步屏障消息时,会将异步消息取出执行。

第三层 (TraversalRunnable)

===================================================================================

当 VSync 信号量到达时,Choreographer 会发送一个异步消息。当异步消息执行时,会触发 ViewRootImpl.mTraversalRunnable() 回调。

final class TraversalRunnable implements Runnable {

@Override

public void run() { <

  • 11
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值