ViewRoot / ViewRootImpl 분석
이 문장 은 위의 문장 부분의 내용 에 대한 총 결 이다.
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);
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.