欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android布局控件View?ViewRootImpl?WindowManagerService關(guān)系

 更新時間:2023年02月10日 09:51:09   作者:One_Month  
這篇文章主要為大家介紹了Android布局控件View?ViewRootImpl?WindowManagerService關(guān)系示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

1. View,ViewRoot和WindowManager簡單介紹

1.1 View和ViewGroup

Android的基本布局控件,結(jié)構(gòu)是樹裝,ViewGroup實現(xiàn)了ViewParent接口,每個View內(nèi)部保留一個ViewParent變量,代表他的父節(jié)點

1.2 ViewRootImpl

ViewRoot概念的具體實現(xiàn)類,也實現(xiàn)了ViewParent接口,每個View樹頂級ViewParent就是這個類,主要管理

  • View樹的measure,layout,draw
  • 向WindowManagerService注冊Window
  • 接收WindowManagerService的事件回調(diào)

1.3 WindowManager

具體實現(xiàn)類WindowManagerImpl,不過最終任務(wù)委托給了WindowManagerGlobal對象,負責建立WindowManagerService連接和通信

ViewRootImpl的功能相當于中介,左手掌握的頂級View,右手掌握WindowManger通信

2. ViewRootImpl的起源

2.1 ViewRootImpl創(chuàng)建時機

這個和WindowManager是有點關(guān)聯(lián)的,起點一般是Activity調(diào)用resume的時機,這個具體是在ActivityThread類中的

public final class ActivityThread {
    final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
        if (r.window == null && !a.mFinished && willBeVisible) {
            r.window = r.activity.getWindow();
            View decor = r.window.getDecorView();
            decor.setVisibility(4);
            wm = a.getWindowManager();
            LayoutParams l = r.window.getAttributes();
            a.mDecor = decor;
            l.type = 1;
            l.softInputMode |= forwardBit;
            if (r.mPreserveWindow) {
                a.mWindowAdded = true;
                r.mPreserveWindow = false;
                ViewRootImpl impl = decor.getViewRootImpl();
                if (impl != null) {
                    impl.notifyChildRebuilt();
                }
            }
            if (a.mVisibleFromClient) {
                if (!a.mWindowAdded) {
                    a.mWindowAdded = true;
                    // 核心
                    wm.addView(decor, l);
                } else {
                    a.onWindowAttributesChanged(l);
                }
            }
        } else if (!willBeVisible) {
            r.hideForNow = true;
        }
    }
}

wm.addView()函數(shù)是入口,wm實際是WindowManager對象,WindowManager真正做工作的類是WindowManagerGlobal

addView()實際上是添加的DecorView ,從r.window獲取(Activity的話window實現(xiàn)類是PhoneWindow)

public final class WindowManagerGlobal {
    public void addView(View view, android.view.ViewGroup.LayoutParams params, Display display, Window parentWindow) {
                // 省略非必要代碼
                ViewRootImpl root = new ViewRootImpl(view.getContext(), display);
                view.setLayoutParams(wparams);
                this.mViews.add(view);
                this.mRoots.add(root);
                this.mParams.add(wparams);
                try {
                    root.setView(view, wparams, panelParentView);
                } catch (RuntimeException var13) {
                    if (index >= 0) {
                        this.removeViewLocked(index, true);
                    }
                    throw var13;
                }
            }
        }
    }
}

這時候創(chuàng)建了ViewRootImpl對象,并把View,ViewRootImpl和windowManagerParam保存到WindowManagerGlobal的集合中,root.setView() 負責接力下一棒

2.2 ViewRootImpl通知注冊Window

public final class ViewRootImpl implements ViewParent, Callbacks, DrawCallbacks {
public void setView(View view, LayoutParams attrs, View panelParentView) {
    synchronized(this) {
        if (this.mView == null) {
            this.mView = view;
            // 省略代碼
            try {
                this.mOrigWindowType = this.mWindowAttributes.type;
                this.mAttachInfo.mRecomputeGlobalAttributes = true;
                this.collectViewAttributes();
                /**
                * 核心
                */
                res = this.mWindowSession.addToDisplay(this.mWindow, this.mSeq, this.mWindowAttributes, this.getHostVisibility(), this.mDisplay.getDisplayId(), this.mAttachInfo.mContentInsets, this.mAttachInfo.mStableInsets, this.mAttachInfo.mOutsets, this.mInputChannel);
            } catch (RemoteException var19) {
                this.mAdded = false;
                this.mView = null;
                this.mAttachInfo.mRootView = null;
                this.mInputChannel = null;
                this.mFallbackEventHandler.setView((View)null);
                this.unscheduleTraversals();
                this.setAccessibilityFocus((View)null, (AccessibilityNodeInfo)null);
                throw new RuntimeException("Adding window failed", var19);
            } finally {
                if (restore) {
                    attrs.restore();
                }
            }
        }
    }
}
}

ViewRootImpl保存和View對象,這里我們也可以發(fā)現(xiàn) 每一個頂級View都會對應(yīng)一個ViewRootImpl對象,this.mWindowSession.addToDisplay() 通過WindowSession通知WindowManagerService注冊Window

3.ViewRootImpl與WindowManagerService的通信

3.1 WindowSession

ViewRootImpl向WindowManagerService發(fā)送信息的類,實際上是一個AIDL接口

public interface IWindowSession extends IInterface {}

ViewRootImpl通過WindowManagerGlobal.getWindowSession() 獲取WindowSession對象

public static IWindowSession getWindowSession() {
        synchronized (WindowManagerGlobal.class) {
            if (sWindowSession == null) {
                try {
                    // Emulate the legacy behavior.  The global instance of InputMethodManager
                    // was instantiated here.
                    // TODO(b/116157766): Remove this hack after cleaning up @UnsupportedAppUsage
                    InputMethodManager.ensureDefaultInstanceForDefaultDisplayIfNecessary();
                    IWindowManager windowManager = getWindowManagerService();
                    sWindowSession = windowManager.openSession(
                            new IWindowSessionCallback.Stub() {
                                @Override
                                public void onAnimatorScaleChanged(float scale) {
                                    ValueAnimator.setDurationScale(scale);
                                }
                            });
                } catch (RemoteException e) {
                    throw e.rethrowFromSystemServer();
                }
            }
            return sWindowSession;
        }
    }

前面注冊Window的時候就用到的的就是WindowSession對象的addToDisplay

3.2 IWindow

這個也是一個AIDL接口文件,主要是用于WindowManagerService向ViewRootImpl發(fā)送消息,ViewRootImpl調(diào)用mWindowSession.addToDisplay注冊窗口,會把IWindow這個信使帶給WindowManagerService

public final class ViewRootImpl implements ViewParent, Callbacks, DrawCallbacks {
    static class W extends android.view.IWindow.Stub {
        private final WeakReference<ViewRootImpl> mViewAncestor;
        private final IWindowSession mWindowSession;
        W(ViewRootImpl viewAncestor) {
            this.mViewAncestor = new WeakReference(viewAncestor);
            this.mWindowSession = viewAncestor.mWindowSession;
        }
        public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw, MergedConfiguration mergedConfiguration, Rect backDropFrame, boolean forceLayout, boolean alwaysConsumeNavBar, int displayId) {
           // 省略實現(xiàn)
        }
        public void moved(int newX, int newY) {
            // 省略實現(xiàn)
        }
        public void dispatchAppVisibility(boolean visible) {
            // 省略實現(xiàn)
        }
        public void dispatchGetNewSurface() {
            // 省略實現(xiàn)
        }
        public void windowFocusChanged(boolean hasFocus, boolean inTouchMode) {
            // 省略實現(xiàn)
        }
        private static int checkCallingPermission(String permission) {
            // 省略實現(xiàn)
        }
        public void executeCommand(String command, String parameters, ParcelFileDescriptor out) {
            // 省略實現(xiàn)
        }
        public void closeSystemDialogs(String reason) {
           // 省略實現(xiàn)
        }
        public void dispatchWallpaperOffsets(float x, float y, float xStep, float yStep, boolean sync) {
          // 省略實現(xiàn)
        }
        public void dispatchWallpaperCommand(String action, int x, int y, int z, Bundle extras, boolean sync) {
          // 省略實現(xiàn)
        }
        public void dispatchDragEvent(DragEvent event) {
          // 省略實現(xiàn)
        }
        public void updatePointerIcon(float x, float y) {
        // 省略實現(xiàn)
        }
        public void dispatchSystemUiVisibilityChanged(int seq, int globalVisibility, int localValue, int localChanges) {
            // 省略實現(xiàn)
        }
        public void dispatchWindowShown() {
            // 省略實現(xiàn)
        }
        public void requestAppKeyboardShortcuts(IResultReceiver receiver, int deviceId) {
           // 省略實現(xiàn)
        }
        public void dispatchPointerCaptureChanged(boolean hasCapture) {
            // 省略實現(xiàn)
        }
    }
}

我們比較熟悉的可能就是WindowFocusChanged這個函數(shù)

4. ViewRootImpl與View

這兩個關(guān)系緊密,我們最容易接觸到的是ViewRootImpl控制者View的刷新

void scheduleTraversals() {
    if (!this.mTraversalScheduled) {
        this.mTraversalScheduled = true;
        this.mTraversalBarrier = this.mHandler.getLooper().getQueue().postSyncBarrier();
        this.mChoreographer.postCallback(2, this.mTraversalRunnable, (Object)null);
        if (!this.mUnbufferedInputDispatch) {
            this.scheduleConsumeBatchedInput();
        }
        this.notifyRendererOfFramePending();
        this.pokeDrawLockIfNeeded();
    }
}

scheduleTraversals是刷新方法的起點:

主線程Handler設(shè)置同步屏障(postSyncBarrier),讓刷新任務(wù)先執(zhí)行

注冊mChoreographer.postCallback()接收界面更新的同步消息

接收到刷新的同步消息后,執(zhí)行mTraversalRunnable的run方法,調(diào)用ViewRootImpl.doTraversal()

void doTraversal() {
    if (this.mTraversalScheduled) {
        this.mTraversalScheduled = false;
        this.mHandler.getLooper().getQueue().removeSyncBarrier(this.mTraversalBarrier);
        if (this.mProfile) {
            Debug.startMethodTracing("ViewAncestor");
        }
        this.performTraversals();
        if (this.mProfile) {
            Debug.stopMethodTracing();
            this.mProfile = false;
        }
    }
}

this.performTraversals()內(nèi)部調(diào)用performMeasure, performLayout, performDraw View樹的measure,layout和draw實現(xiàn)刷新

以上就是Android布局控件View ViewRootImpl WindowManagerService關(guān)系的詳細內(nèi)容,更多關(guān)于Android布局控件的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Android使用元數(shù)據(jù)實現(xiàn)配置信息的傳遞方法詳細介紹

    Android使用元數(shù)據(jù)實現(xiàn)配置信息的傳遞方法詳細介紹

    這篇文章主要介紹了Android使用元數(shù)據(jù)實現(xiàn)配置信息的傳遞方法,也就是實現(xiàn)配置快捷菜單功能,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧
    2022-09-09
  • Android RecycleView添加head配置封裝的實例

    Android RecycleView添加head配置封裝的實例

    這篇文章主要介紹了Android RecycleView添加head配置封裝的實例的相關(guān)資料,這里提供實例幫助大家實現(xiàn)這樣的功能,需要的朋友可以參考下
    2017-08-08
  • 簡介Android 中的AsyncTask

    簡介Android 中的AsyncTask

    AsyncTask是一個很常用的API,尤其異步處理數(shù)據(jù)并將數(shù)據(jù)應(yīng)用到視圖的操作場合。接下來通過本文給大家介紹Android 中的AsyncTask,感興趣的朋友一起學習吧
    2016-03-03
  • Android網(wǎng)絡(luò)通信基礎(chǔ)類源碼分析講解

    Android網(wǎng)絡(luò)通信基礎(chǔ)類源碼分析講解

    這篇文章主要介紹了Android網(wǎng)絡(luò)通信基礎(chǔ)類源碼,包括了Handler、Looper、Thread的分析講解,對日常開發(fā)學習很有幫助,需要的朋友可以參考下
    2024-05-05
  • Android開發(fā)之日歷CalendarView用法示例

    Android開發(fā)之日歷CalendarView用法示例

    這篇文章主要介紹了Android開發(fā)之日歷CalendarView用法,簡單分析了日歷CalendarView組件的功能、屬性設(shè)置方法、界面布局、事件監(jiān)聽等相關(guān)操作技巧,需要的朋友可以參考下
    2019-03-03
  • OpenHarmony實現(xiàn)屏幕亮度動態(tài)調(diào)節(jié)方法詳解

    OpenHarmony實現(xiàn)屏幕亮度動態(tài)調(diào)節(jié)方法詳解

    大家在拿到dayu之后,都吐槽說,會經(jīng)常熄屏,不利于調(diào)試,那么有沒有一種辦法,可以讓app不熄屏呢,答案是有的,今天我們就來揭秘一下,如何控制屏幕亮度
    2022-11-11
  • Android仿qq頂部消息欄效果

    Android仿qq頂部消息欄效果

    這篇文章主要介紹了Android仿qq頂部消息欄效果,需要的朋友可以參考下
    2018-04-04
  • android開發(fā)PathEffect問題處理

    android開發(fā)PathEffect問題處理

    本文主要整理了關(guān)于android中PathEffect的問題匯總以及處理方式,以及給大家做了關(guān)于PathEffect類的詳細解釋。
    2017-11-11
  • 談一談Android內(nèi)存泄漏問題

    談一談Android內(nèi)存泄漏問題

    談一談Android內(nèi)存泄漏問題,圍繞內(nèi)存泄露的定義、內(nèi)存泄露的原理、內(nèi)存泄露的解決方法進行探討,感興趣的小伙伴們可以參考一下
    2016-01-01
  • Android 8.0安裝apk的實例代碼

    Android 8.0安裝apk的實例代碼

    本文給大家分享了Android 8.0安裝apk的實例代碼,非常不錯,具有參考借鑒價值,需要的朋友參考下吧
    2018-03-03

最新評論