AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當前位置:首頁 > 科技  > 軟件

ViewRootImpl如何負責管理繪制視圖樹和刷新界面

來源: 責編: 時間:2024-05-22 17:14:37 173觀看
導讀ViewRootImpl位于視圖層次結構的頂部,負責View和WindowManager之間的通信。視圖繪制:負責調用View樹的繪制流程,包括測量(measure)、布局(layout)和繪制(draw)等操作。監聽View樹的改變,并根據需要觸發相應的繪制操作,確保界面的

ViewRootImpl位于視圖層次結構的頂部,負責View和WindowManager之間的通信。PjX28資訊網——每日最新資訊28at.com

  1. 視圖繪制:負責調用View樹的繪制流程,包括測量(measure)、布局(layout)和繪制(draw)等操作。監聽View樹的改變,并根據需要觸發相應的繪制操作,確保界面的及時更新。
  2. 事件分發:負責將輸入的各種事件(如觸摸事件、按鍵事件等)分發給正確的View處理。根據觸摸事件的位置信息,逐層遍歷View樹,找到最合適的View來處理事件。將處理結果返回給系統,以便進行后續的處理,如滾動、點擊等。
  3. 窗口管理:承擔Android窗口管理的一部分職責。負責創建和管理窗口,將窗口與ViewRootImpl進行綁定。當窗口需要顯示或隱藏時,ViewRootImpl會相應地調整界面的顯示狀態。

ViewRootImpl關聯了多個類和接口,IWindowSession、Choreographer及其FrameCallback接口等。IWindowSession用于客戶端和WindowManagerService之間進行窗口管理操作的接口,允許ViewRootImpl與WindowManagerService進行通信,執行如添加、刪除、更新窗口等操作。PjX28資訊網——每日最新資訊28at.com

scheduleTraversals

scheduleTraversals()方法負責將一次視圖遍歷(traversal)排期到其調度計劃中,但并不會立即執行遍歷操作。方法被許多操作所調用,比如當視圖的大小、位置等屬性發生變化時,或者當調用requestLayout()、invalidate()等方法時,都會觸發scheduleTraversals()。作用是將視圖的測量、布局和繪制操作(即遍歷操作)放入待執行隊列中,并注冊一個底層的刷新信號監聽器。PjX28資訊網——每日最新資訊28at.com

public void invalidate(boolean invalidateCache) {    invalidateInternal(0, 0, mRight - mLeft, mBottom - mTop, invalidateCache, true);}void invalidateInternal(int l, int t, int r, int b, boolean invalidateCache, boolean fullInvalidate) {    ...    // Propagate the damage rectangle to the parent view.    final AttachInfo ai = mAttachInfo;    final ViewParent p = mParent;    if (p != null && ai != null && l < r && t < b) {        final Rect damage = ai.mTmpInvalRect;        damage.set(l, t, r, b);        //調用父容器的方法,向上傳遞事件        p.invalidateChild(this, damage);    }    ...}public final void invalidateChild(View child, final Rect dirty) {    .....    ViewParent parent = this;        do {            View view = null;            if (parent instanceof View) {                view = (View) parent;            }            if (drawAnimation) {                if (view != null) {                    view.mPrivateFlags |= PFLAG_DRAW_ANIMATION;                } else if (parent instanceof ViewRootImpl) {                    ((ViewRootImpl) parent).mIsAnimating = true;                }            }            // If the parent is dirty opaque or not dirty, mark it dirty with the opaque            // flag coming from the child that initiated the invalidate            if (view != null) {                if ((view.mViewFlags & FADING_EDGE_MASK) != 0 && view.getSolidColor() == 0) {                    opaqueFlag = PFLAG_DIRTY;                }                if ((view.mPrivateFlags & PFLAG_DIRTY_MASK) != PFLAG_DIRTY) {                    view.mPrivateFlags = (view.mPrivateFlags & ~PFLAG_DIRTY_MASK) | opaqueFlag;                }            }            //調用ViewGrup的invalidateChildInParent,如果已經達到最頂層view,則調用ViewRootImpl的invalidateChildInParent。            parent = parent.invalidateChildInParent(location, dirty);            if (view != null) {                // Account for transform on current parent                Matrix m = view.getMatrix();                if (!m.isIdentity()) {                    RectF boundingRect = attachInfo.mTmpTransformRect;                    boundingRect.set(dirty);                    m.mapRect(boundingRect);                    dirty.set((int) Math.floor(boundingRect.left),                              (int) Math.floor(boundingRect.top),                              (int) Math.ceil(boundingRect.right),                              (int) Math.ceil(boundingRect.bottom));                }            }        } while (parent != null);    }}

當VSYNC信號到來時(VSYNC信號是Android系統中用于同步屏幕刷新的信號),系統會從待執行隊列中取出對應的scheduleTraversals()操作,并將其加入到主線程的消息隊列中。然后,主線程會從消息隊列中取出并執行這個操作,進而觸發視圖的測量、布局和繪制流程。PjX28資訊網——每日最新資訊28at.com

private void scheduleFrameLocked(long now) {    if (!mFrameScheduled) {        mFrameScheduled = true;        if (USE_VSYNC) {            //這里判斷,當前執行的線程是否是創建該Choreographer的線程,如果是直接執行。否則通過handler 發送到 創建該Choreographer的線程去執行。            if (isRunningOnLooperThreadLocked()) {                scheduleVsyncLocked();            } else {                //這條message 最后處理還是調用到了scheduleVsyncLocked方法                Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_VSYNC);                msg.setAsynchronous(true);                mHandler.sendMessageAtFrontOfQueue(msg);            }        } else {            final long nextFrameTime = Math.max(                    mLastFrameTimeNanos / TimeUtils.NANOS_PER_MS + sFrameDelay, now);            if (DEBUG_FRAMES) {                Log.d(TAG, "Scheduling next frame in " + (nextFrameTime - now) + " ms.");            }            Message msg = mHandler.obtainMessage(MSG_DO_FRAME);            msg.setAsynchronous(true);            mHandler.sendMessageAtTime(msg, nextFrameTime);        }    }}private void scheduleVsyncLocked() {    mDisplayEventReceiver.scheduleVsync();}public void scheduleVsync() {    if (mReceiverPtr == 0) {        Log.w(TAG, "Attempted to schedule a vertical sync pulse but the display event " + "receiver has already been disposed.");    } else {        nativeScheduleVsync(mReceiverPtr);    }}

在這個過程中,performTraversals()方法會被調用。方法會執行實際的測量、布局和繪制操作。首先會調用measureHierarchy()方法進行測量,然后調用performLayout()方法進行布局,最后調用draw()方法進行繪制。這些操作會按照順序執行,以確保視圖能夠正確地顯示在屏幕上。最終通過nativeScheduleVsync()原生方法通知屏幕進行繪制。PjX28資訊網——每日最新資訊28at.com

performTraversals

performTraversals()方法負責啟動視圖的測量(measure)、布局(layout)和繪制(draw)流程。當需要創建視圖、視圖參數改變或界面需要刷新時,可能會從根視圖DecorView開始重新進行測量、布局和繪制,這時就會調用到performTraversals()方法。PjX28資訊網——每日最新資訊28at.com

private void performTraversals() {    ...    performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);    ...    performLayout(lp, desiredWindowWidth, desiredWindowHeight);    ...     performDraw();}void doTraversal() {      //防止重入    if (mTraversalScheduled) {        mTraversalScheduled = false;        //移除同步屏障        mHandler.getLooper().getQueue()                    .removeSyncBarrier(mTraversalBarrier);        performTraversals();    }}

圖片圖片PjX28資訊網——每日最新資訊28at.com

  1. 「測量(Measure)」:在這個階段,系統會遍歷整個視圖樹,計算每個視圖的大小。這個過程中會用到MeasureSpec,每個MeasureSpec都包含了一個測量模式和測量大小,測量模式主要有三種:EXACTLY(父視圖已經確定了子視圖的確切大小)、AT_MOST(子視圖的大小有一個最大值限制)和UNSPECIFIED(父視圖對子視圖的大小沒有要求)。
  2. 「布局(Layout)」:在測量完成后,系統會為每個視圖確定其在屏幕上的精確位置。這個過程中,父視圖會根據測量階段得到的子視圖大小以及自身的布局參數,計算出子視圖應該放置的位置。
  3. 「繪制(Draw)」:系統會遍歷整個視圖樹,根據每個視圖的繪制參數(如顏色、形狀等)將其繪制到屏幕上。這個過程中,視圖會按照其在視圖樹中的層次順序進行繪制,先繪制父視圖,再繪制子視圖。
final TraversalRunnable mTraversalRunnable = new TraversalRunnable();void scheduleTraversals() {    if (!mTraversalScheduled) {        //移除同步屏障        mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();        mChoreographer.postCallback(                Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);               }}void unscheduleTraversals() {    mChoreographer.removeCallbacks(                    Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);    }}public void postCallback(int callbackType, Runnable action, Object token) {    postCallbackDelayed(callbackType, action, token, 0);}public void postCallbackDelayed(int callbackType,    Runnable action, Object token, long delayMillis) {    ...    postCallbackDelayedInternal(callbackType, action, token, delayMillis);}private void postCallbackDelayedInternal(int callbackType,    Object action, Object token, long delayMillis) {    ....    synchronized (mLock) {        final long now = SystemClock.uptimeMillis();        final long dueTime = now + delayMillis;        //把 任務添加到了mCallbackQueues 回調里面去,等待回調執行。        mCallbackQueues[callbackType].addCallbackLocked(dueTime, action, token);                    //now=0 ,走進scheduleFrameLocked()方法內        if (dueTime <= now) {            scheduleFrameLocked(now);        } else {            Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_CALLBACK, action);            msg.arg1 = callbackType;            msg.setAsynchronous(true);            mHandler.sendMessageAtTime(msg, dueTime);        }    }}//Choreographer內部類DisplayEventReceiver,重寫了onVsync方法@Overridepublic void onVsync(long timestampNanos, int builtInDisplayId, int frame) {    mTimestampNanos = timestampNanos;    mFrame = frame;    Message msg = Message.obtain(mHandler, this);    // 設置成異步消息    msg.setAsynchronous(true);    mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS);}public void run() {    mHavePendingVsync = false;    doFrame(mTimestampNanos, mFrame);}// Choreographervoid doFrame(long frameTimeNanos, int frame) {    ...    doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos);}void doCallbacks(int callbackType, long frameTimeNanos) {    CallbackRecord callbacks;    // 從mCallbackQueues取出    callbacks = mCallbackQueues[callbackType].extractDueCallbacksLocked(now / TimeUtils.NANOS_PER_MS);    for (CallbackRecord c = callbacks; c != null; c = c.next) {         c.run(frameTimeNanos);    }}// CallbackRecordpublic void run(long frameTimeNanos) {    if (token == FRAME_CALLBACK_TOKEN) {        ((FrameCallback)action).doFrame(frameTimeNanos);    } else {        // 這里也即是調用了TraservalRunnable的run方法,也即是三個繪制流程        ((Runnable)action).run();    }}

mHandler是當前主線程的handler,當接收到onVsync信號的時候,將自己封裝到Message中,等到Looper處理,最后Looper處理消息的時候就會調用run方法最終從mCallbackQueues取回之前添加的任務再執行run方法,也就是TraservalRunnable的run方法。最終觸發performTraversals方法進行界面刷新。PjX28資訊網——每日最新資訊28at.com

本文鏈接:http://www.tebozhan.com/showinfo-26-90041-0.htmlViewRootImpl如何負責管理繪制視圖樹和刷新界面

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: Vue3 實現最近很火的酷炫功能:卡片懸浮發光

下一篇: 我們忘記了前端基礎知識

標簽:
  • 熱門焦點
  • 摸魚心法第一章——和配置文件說拜拜

    為了能摸魚我們團隊做了容器化,但是帶來的問題是服務配置文件很麻煩,然后大家在群里進行了“親切友好”的溝通圖片圖片圖片圖片對比就對比,簡單對比下獨立配置中心和k8s作為配
  • 如何通過Python線程池實現異步編程?

    線程池的概念和基本原理線程池是一種并發處理機制,它可以在程序啟動時創建一組線程,并將它們置于等待任務的狀態。當任務到達時,線程池中的某個線程會被喚醒并執行任務,執行完任
  • 慕巖炮轟抖音,百合網今何在?

    來源:價值研究所 作者:Hernanderz&ldquo;難道就因為自己的一個產品牛逼了,從客服到總裁,都不愿意正視自己產品和運營上的問題,選擇逃避了嗎?&rdquo;這一番話,出自百合網聯合創
  • 騰訊蓋樓,字節拆墻

    來源 | 光子星球撰文 | 吳坤諺編輯 | 吳先之&ldquo;想重溫暴刷深淵、30+技能搭配暴搓到爽的游戲體驗嗎?一起上晶核,即刻暴打!&rdquo;曾憑借直播騰訊旗下代理格斗游戲《DNF》一
  • 自律,給不了Keep自由!

    來源 | 互聯網品牌官作者 | 李大為編排 | 又耳 審核 | 谷曉輝自律能不能給用戶自由暫時不好說,但大概率不能給Keep自由。近日,全球最大的在線健身平臺Keep正式登陸港交所,努力
  • 華為HarmonyOS 4升級計劃公布:首批34款機型今日開啟公測

    8月4日消息,今天下午華為正式發布了HarmonyOS 4系統,在更流暢的前提下,還帶來了不少新功能,UI設計也有變化,會讓手機煥然一新。華為宣布,首批機型將會在
  • iQOO Neo8 Pro搶先上架:首發天璣9200+ 安卓性能之王

    經過了一段時間的密集爆料,昨日iQOO官方如期對外宣布:將于5月23日推出全新的iQOO Neo8系列新品,官方稱這是一款擁有旗艦級性能調校的作品。隨著發布時
  • 質感不錯!OPPO K11渲染圖曝光:旗艦IMX890傳感器首次下放

    一直以來,OPPO K系列機型都保持著較為均衡的產品體驗,歷來都是2K價位的明星機型,去年推出的OPPO K10和OPPO K10 Pro兩款機型憑借各自的出色配置,堪稱有
  • 世界人工智能大會國際日開幕式活動在世博展覽館開啟

    30日上午,世界人工智能大會國際日開幕式活動在世博展覽館開啟,聚集國際城市代表、重量級院士專家、國際創新企業代表,共同打造人工智能交流平臺。上海市副市
Top