<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
進入View
的measure
方法:
void measure(){ boolean forceLayout = (mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT; boolean specChanged = widthMeasureSpec != mOldWidthMeasureSpec || heightMeasureSpec != mOldHeightMeasureSpec; boolean isSepcExactly = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY && MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY; boolean matchesSpecSize = getMeasuredWidth() == MeasureSpec.getSize(widthMeasureSpec) && getMeasuredHeight() == MeasureSpec.getSize(heightMeasureSpec); final boolean needsLayout = specChanged && (sAlwaysRemeasureExactly || !isSpecExactly || !matchesSpecSize); if(forceLayout || needLayout){ int cacheIndex = forceLayout ? -1 : mMeasureCache.indexOfKey(key); if (cacheIndex < 0 || sIgnoreMeasureCache) { onMeasure(widthMeasureSpec, heightMeasureSpec); mPrivateFlags3 &= ~PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT; } else { long value = mMeasureCache.valueAt(cacheIndex); setMeasuredDimensionRaw((int) (value >> 32), (int) value); mPrivateFlags3 |= PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT; } } }
什麼時候forceLayout=true
:
requestLayout
forceRequestLayout
什麼時候needsLayout=true
:
什麼時候呼叫了onMeasure>
方法:
forceLayouy=true
mMeasureCache
沒有當前的快取總結:
當呼叫了requestLayout
一定會測發重測過程.當forceLayout=false
的時候會去判斷mMeasureCache
值.現在研究下這個mMeasureCache
class View{ LongSparseLongArray mMeasureCache; void measure(widthSpec,heightSpec){ --- long key = (long) widthMeasureSpec << 32 | (long) heightMeasureSpec & 0xffffffffL; int cacheIndex = forceLayout ? -1 : mMeasureCache.indexOfKey(key); if(cacheIndex<0){ onMeasure(widthSpec,heightSpec); } mOldWidthMeasureSpec = widthMeasureSpec; mOldHeightMeasureSpec = heightMeasureSpec; mMeasureCache.put(key,widhSpec|heightSpec); --- } }
這裡可以看到oldWidthMeasureSpec
和mMeasureCache
都是快取上一次的值,那他們有什麼不同呢?不同點就是,oldWidthMeasureSpec>
不僅僅快取了測量的spec
模式而且快取了size
.但是mMeasureCache
只快取了size
.從這行程式碼可以看出:
long key = (long) widthMeasureSpec << 32 | (long) heightMeasureSpec & 0xffffffffL;
這裡一同運算就為了排除掉spec
造成的影響.
//不信你可以試下下面的程式碼 public class Test { public static void main(String[] args) { long widthMeasureSpec = makeMeasureSpec(10,0); long heightMeasureSpec = makeMeasureSpec(20,0); long ss = widthMeasureSpec << 32 | (long) heightMeasureSpec & 0xffffffffL; System.out.println("=========="+ss); } private static final int MODE_MASK = 0x3 << 30; public static int makeMeasureSpec(int size, int mode) { return (size & ~MODE_MASK) | (mode & MODE_MASK); } } //42949672980 //42949672980 //42949672980
什麼時候mPrivateFlags
會被賦值PFLAG_FORCE_LAYOUT
.
在view viewGrouup
的建構函式裡面會主動賦值一次,然後在ViewGroup.addView
時候會給當前View
的mProvateFlags
賦值PFLAG_FORCE_LAYOUT
.
void measure(int widthMeasureSpec,int heightMeasureSpec){ ---- boolean forceLayout = (mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT; if(forceLayout | needsLayout){ onMeasure() } ---- } public void layout(int l, int t, int r, int b){ --- mPrivateFlags &= ~PFLAG_FORCE_LAYOUT; --- }
在第一次觸發到measure
方法時,forceLayoyt=true needsLayout=true
,但是layout
方法還沒觸發到.
在第二次觸發到measure>
方法時,forceLayout=true needsLayout=false
,所以還是會進入onMeasure
方法.這次會執行layout
方法.然後我們在下次的時候forceLayout
就等於false
了.上面的這一段分析是分析的measure
內部如何防止多次呼叫onMeasure
.
在Activity
執行到onResume
生命週期的時候,會執行WindowManager.addView
操作,WindowManager
的具體實現類是WindowManagerImpl
然後addView
操作交給了代理類WindowManagerGlobal
,然後在WindowManagerGlobal
的addView
裡面執行了ViewRootImpl.setView
操作(ViewRootImpl
物件也是在這個時候建立的),在ViewRootImpl
會主動呼叫一次requestLayout
,也就開啟了第一次的檢視 測量 佈局 繪製.
在setView
的時候主動呼叫了一次ViewRootImpl.requestLayout
,注意這個requestLayout
是ViewRootImpl
的內部方法,和view viewGroup
那些requestLayout
不一樣.在ViewRootImpl.requestLayout
內部呼叫了performTraversals
方法:
class ViewRootImpl{ void performTraversals(){ if(layoutResuested){ //標記1 windowSizeMayChanged |= measureHierarchy(host,lp,res,desiredWindowWidth,desiredWindowHeight); } //標記2 performMeasure() performLayout() } void measureHierarchy(){ performMeasure() } }
從ViewRootImpl
的執行邏輯你可以看出,在執行performLayout
之前,他自己就已經呼叫了兩次performMeasure
方法.所以你現在就知道為啥了.
以上就是onMeasure被執行兩次原理解析的詳細內容,更多關於onMeasure被執行兩次的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45