Written by
im jin hyeon
on
on
윈도우 매니저
SurfaceFlinger::
여러 개의 Surface를 하나의 Surface로 만들고 만든 화면을 프레임 버퍼 드라이버와 연계하여 프레임 버퍼로 만들고, (프레임버퍼에 등록?)LCD 화면에 표시하는 역할surface :: 창
새창추가 = 새 surface할당
WindowManager :: 애플리케이션과 WindowManagerSerivce 간의 소통interface
ViewManager를 상속하여 구현됨
public interface ViewManager{
/ / Add View
public void addView(View view, ViewGroup.LayoutParams params);
/ / Update View
public void updateViewLayout(View view, ViewGroup.LayoutParams params);
/ / Delete View
public void removeView(View view);
}Copy code
1.Add 2.Update 3.Delete ㅡ3개의 method를 가짐
WindowManager 의 구현클래스 = WindowManagerImpl
WindowManagerImpl의 기능구현클래스 = WindowManagerGlobal
public final class WindowManagerGlobal {
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow) {
/ / Check the validity of the parameters
...
//ViewRootImpl encapsulates the interaction between View and WindowManager
ViewRootImpl root;
View panelParentView = null;
synchronized (mLock) {
// Start watching for system property changes.
if (mSystemPropertyUpdater == null) {
mSystemPropertyUpdater = new Runnable() {
@Override public void run() {
synchronized (mLock) {
for (int i = mRoots.size() - 1; i >= 0; --i) {
mRoots.get(i).loadSystemProperties();
}
}
}
};
SystemProperties.addChangeCallback(mSystemPropertyUpdater);
}
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.
if (wparams.type >= WindowManager.LayoutParams.FIRST_SUB_WINDOW &&
wparams.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
final int count = mViews.size();
for (int i = 0; i < count; i++) {
if (mRoots.get(i).mWindow.asBinder() == wparams.token) {
panelParentView = mViews.get(i);
}
}
}
/ / Build ViewRootImpl through the context
root = new ViewRootImpl(view.getContext(), display);
view.setLayoutParams(wparams);
//mViews stores all View objects corresponding to Window
mViews.add(view);
//mRoots stores all ViewRootImpl objects corresponding to Window
mRoots.add(root);
//mParams stores all WindowManager.LayoutParams objects corresponding to Window
mParams.add(wparams);
}
// do this last because it fires off messages to start doing things
try {
/ / Call the ViewRootImpl.setView () method to complete the addition of Window and update the interface
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;
}
}
}Copy code
중요멤버
mViews view 객체 저장
mRoots ViewRootImpl 객체 저장
mParams WindowManager.LayoutParams 객체 저장
ViewRootImpl 클래스:: View와 WindowManager간 상호작용을 캡슐화하는 래퍼클래스
ViewRootImpl.setView() 호출 :::창의 추가와 업데이트완료를 위해