ViewRoot / ViewRootImpl 분석

6155 단어 Android소스 코드
원문 Android 의 ViewRootImpl 류 소스 코드 분석 http://blog.csdn.net/qianhaifeng2012/article/details/51737370
이 문장 은 위의 문장 부분의 내용 에 대한 총 결 이다.
ViewRoot 와 ViewRootImpl 은 말 그대로 ViewRootImpl 이 ViewRoot 의 실현 인 줄 알 았 는데 사실은 그렇지 않 았 다.뷰 루트 는 안 드 로 이 드 2.2 이전 이 고 2.2 이후 뷰 루트 임 플 로 대체 되 었 다. 
ViewRootImpl 의 역할:
1. Window Manager 와 DecorView 의 유대
2. View 를 그립 니 다. permMeasure () 를 호출 했 습 니 다. performLayout(), permDraw () 방법 을 사용 하여 View 의 measure, layot, draw 방법 으로 view 를 그립 니 다.
3. 버튼, 터치 스크린 등 각종 이벤트 이 벤트 를 View 에 전달 합 니 다.
ViewRootImpl
ViewRootImpl 은 나무 구조의 꼭대기 이지 만 View 가 아 닙 니 다. View 와 Window Manager 의 통신 협 의 를 실 현 했 고 대부분 실현 디 테 일 은 Window Manager Global 류 에 있 습 니 다.
WindowManager
Window Manager 는 주로 view 를 추가, 삭제, 변경 하 는 세 가지 방법 이 있 으 며, 이 세 가지 방법 은 View Manager 를 계승 하여 얻 은 것 이다.또한 이 세 가지 방법 은 Window Manager 의 실현 류 Window Manager Impl 에 의 해 이 루어 진 것 이 고 Window Manager Impl 은 세 가지 방법 에 대한 실현 은 Window Manager Global 의 구체 적 인 방법 을 호출 하여 이 루어 진 것 이다.
WindowManagerGlobal
Window 에 직접 접근 할 수 없습니다. Window Manger 를 통 해 Window 를 방문 해 야 합 니 다. Window Manager Impl 은 Window Manager 를 실현 합 니 다. 구체 적 인 실현 에서 Window Manager Global 의 방법 을 호출 했 습 니 다. 예 를 들 어 Window 를 추가 하려 면 Window Manager Global 의 addView 방법 을 호출 했 습 니 다. Window 를 추가 하 는 것 은 바로 View 를 추가 하 는 것 입 니 다. Window 는 추상 적 인 개념 일 뿐 입 니 다.Window Manager Global 에 다음 멤버 변수 가 있 습 니 다.
private final ArrayList mViews = new ArrayList();
private final ArrayList mRoots = new ArrayList();
private final ArrayList mParams =
            new ArrayList();
private final ArraySet mDyingViews = new ArraySet();

mViews 는 모든 Window 에 대응 하 는 View 를 저장 합 니 다. mRoots 는 모든 Window 에 대응 하 는 ViewRootImpl 을 저장 합 니 다. mParams 는 모든 Window 에 대응 하 는 레이아웃 매개 변 수 를 저장 합 니 다. mDyingViews 는 삭제 되 고 있 는 View 대상 을 저장 하거나 removeView 방법 을 호출 했 지만 삭제 되 지 않 은 Window 대상 을 저장 합 니 다.
 Window Manager Global 의 addView 방법: Window 를 추가 하 는 것 입 니 다.
    public void addView(View view, ViewGroup.LayoutParams params,
            Display display, Window parentWindow) {
        //              ,    
        ...
 
        ViewRootImpl root;
        View panelParentView = null;
 
        synchronized (mLock) {
            // Start watching for system property changes.
            ...
 
            int index = findViewLocked(view, false);
            if (index >= 0) {
                if (mDyingViews.contains(view)) {
                    // Don't wait for MSG_DIE to make it's way through root's queue.
                    mRoots.get(index).doDie();
                } else {
                    throw new IllegalStateException("View " + view
                            + " has already been added to the window manager.");
                }
                // The previous removeView() had not completed executing. Now it has.
            }
 
            // If this is a panel window, then find the window it is being
            // attached to for future reference.
            ...
            //      ViewRootImpl
            root = new ViewRootImpl(view.getContext(), display);

            //     View    
            view.setLayoutParams(wparams);

            //     View    
            mViews.add(view);

            //     ViewRootImpl    
            mRoots.add(root);

            mParams.add(wparams);
        }
 
        // do this last because it fires off messages to start doing things
        try {

            //       ,    View(    Window)     ViewRootImpl 
            root.setView(view, wparams, panelParentView);

        } catch (RuntimeException e) {
            // BadTokenException or InvalidDisplayException, clean up.
            synchronized (mLock) {
                final int index = findViewLocked(view, false);
                if (index >= 0) {
                    removeViewLocked(index, true);
                }
            }
            throw e;
        }
    }

/ / root. setView (view, wprams, panel ParentView) 에서;이 를 통 해 알 수 있 듯 이 View (Window) 를 진정 으로 추가 한 것 은 ViewRootImpl 입 니 다. root. setView () 방법 에 서 는 requestLayout () 를 호출 하여 비동기 리 셋 요청 을 완 료 했 습 니 다. requestLayout () 는 permTraversals 를 호출 하여 View 를 완성 할 것 입 니 다. 이 어 IWindowSession 의 addToDisplay (mWindow, mSeq, mWindowAttributes 를 통 해 getHostVisibility (), mDisplay. getDisplayId (), mAttachInfo. mContentInsets, mInputChannel) 방법 으로 Window 의 추가 과정 을 완성 합 니 다. IWindowSession 은 Binder 대상 입 니 다. 진정한 실현 유형 은 Session 입 니 다. 즉, 이것 은 IPC 과정 입 니 다. Session 의 addToDisPlay 방법 을 원 격 으로 호출 했 습 니 다. 다음은 세 션 의 addToDisPlay 방법 입 니 다.
    @Override
public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs,
       int viewVisibility, int displayId, Rect outContentInsets,
        InputChannel outInputChannel) {
       return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId,
                outContentInsets, outInputChannel);
 }

Window 의 추가 요청 은 Window Manager Service 에 맡 겼 음 을 알 수 있 습 니 다.addView 는 다음 과 같은 과정 을 거 칩 니 다. WindowManager - > WindowManager Gobal - > ViewRootImpl - > Session - > WindowManager Service
Activity Thread 에 서 는 Activity 대상 이 생 성 되면 DecorView 를 Window 에 추가 하고 ViewRootImpl 대상 을 만 들 며 ViewRootImpl 대상 과 DecorView 를 연결 합 니 다. 코드 를 참고 하 세 요. Actvity Thread 에서 ViewRootImpl 은 DecorView 의 부모 요소 이지 만 ViewRootImpl 은 View 가 아 닙 니 다.
r.window = r.activity.getWindow();
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
//getWindowManager             WindowManager
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode |= forwardBit;
if (a.mVisibleFromClient) {
      a.mWindowAdded = true;
      //WindowManager  decorView
      wm.addView(decor, l);
}

 
   
 

좋은 웹페이지 즐겨찾기