調用鏈:view.invalidate() → parent.invalidateChild() → ... → ViewRootImpl.scheduleTraversals() → Handler 發送 MSG_DO_TRAVERSAL → performTraversals() → draw() → onDraw()
關鍵點:ViewRootImpl 通過 Choreographer 與 VSync 對齊,合併同一幀內多次 invalidate,最終統一執行 performTraversals,保證每幀最多繪製一次。
同一資源 ID 加載的 Drawable 實例共享同一 ConstantState(包含圖片像素、內在寬高、透明度等不可變數據),修改 alpha、colorFilter 等可變屬性時,**直接修改共享狀態**,導致所有引用處同步變化。
public Drawable mutate() {
if (!mutated && constantState != null) {
constantState = constantState.newConstantState(); // 深拷貝 ConstantState
mutated = true;
}
return this;
}
ConstantState,後續屬性修改作用於副本,實現隔離。mutated == true,直接返回自身,不再拷貝。其 ConstantState 內持有 Bitmap 引用,**拷貝 ConstantState 並不複製 Bitmap 像素**,故內存開銷極小,僅隔離透明度、色調等繪製參數。
mutate()**。bitmap.copy() 創建新 Bitmap。DrawableCompat.wrap(drawable).mutate() 兼容舊版本。