转载请注明出处:http://blog.csdn.net/crazy1235/article/details/72625679
关于Window对象管理的相关类:
ViewManager
WindowManager
WindowManagerImpl
WindowManagerGlobal
ViewParent
ViewRootImpl
ActvityThread
WindowManagerService
Window是一个抽象类,具体实现类就是 PhoneWindow !
一个Window是通过一个View来承载的,还对应一个ViewRootImpl!
访问Window必须通过WindowManager来实现!
Window具体操作方法实现实在WindowManagerImpl类中,方法定义在ViewManager接口中!
public interface ViewManager
{
public void addView(View view, ViewGroup.LayoutParams params);
public void updateViewLayout(View view, ViewGroup.LayoutParams params);
public void removeView(View view);
}
ViewManager接口定义了三个函数,分别对应window的添加,更新和删除!
@Override
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
applyDefaultToken(params);
mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
其实WindowManagerImpl也没有做具体的操作,而是交给了 WindowManagerGlobal
在WindowManagerImpl类中进行了初始化
private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
WindowManagerGlobal.java
private WindowManagerGlobal() {
}
public static WindowManagerGlobal getInstance() {
synchronized (WindowManagerGlobal.class) {
if (sDefaultWindowManager == null) {
sDefaultWindowManager = new WindowManagerGlobal();
}
return sDefaultWindowManager;
}
}
很明显看出这是个单例模式!
private final ArrayList mViews = new ArrayList();
private final ArrayList mRoots = new ArrayList();
private final ArrayList mParams =
new ArrayList();
private final ArraySet mDyingViews = new ArraySet();
WindowManagerGlobal中有四个重要的集合!
mViews集合存储了所有window对应的View对象!
mRoots集合存储了所有window对应的ViewRootImpl对象
mParams集合存储了所有window对应的布局参数
mDyingViews集合存储了所有正在被删除的window对象
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow) {
// 1. 验证参数!
if (view == null) {
throw new IllegalArgumentException("view must not be null");
}
if (display == null) {
throw new IllegalArgumentException("display must not be null");
}
if (!(params instanceof WindowManager.LayoutParams)) {
throw new IllegalArgumentException("Params must be WindowManager.LayoutParams");
}
final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
if (parentWindow != null) {
parentWindow.adjustLayoutParamsForSubWindow(wparams);
} else {
final Context context = view.getContext();
if (context != null
&& (context.getApplicationInfo().flags
& ApplicationInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
wparams.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
}
}
ViewRootImpl root; // 一个ViewRootImpl对象
View panelParentView = null; // 一个View对象
synchronized (mLock) {
// ...
// 查找view对应的index
int index = findViewLocked(view, false);
if (index >= 0) {
if (mDyingViews.contains(view)) {// 如果正在被删除的集合包含该view,则执行ViewRootImpl.doDie()函数
mRoots.get(index).doDie();
} else {
throw new IllegalStateException("View " + view
+ " has already been added to the window manager.");
}
}
// ...
// 创建ViewRootImpl对象
root = new ViewRootImpl(view.getContext(), display);
// 设置布局参数
view.setLayoutParams(wparams);
// 添加view到集合中
mViews.add(view);
// 添加ViewRootImpl到集合中
mRoots.add(root);
// 添加wparams参数到集合中
mParams.add(wparams);
}
try {
// 将view设置到ViewRootImpl中!
root.setView(view, wparams, panelParentView);
} catch (RuntimeException e) {
// 设置异常则移除view
synchronized (mLock) {
final int index = findViewLocked(view, false);
if (index >= 0) {
removeViewLocked(index, true);
}
}
throw e;
}
}
函数最后通过ViewRootImpl.setView() 来完成window的添加过程!
在setView()内部调用了requestLayout()开启了绘制流程!
View的绘制流程是由ViewRootImpl来完成的!
requestLayout(); 完成绘制流程之后,通过WindowSession来完成Window的添加过程!
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
// ...
try {
mOrigWindowType = mWindowAttributes.type;
mAttachInfo.mRecomputeGlobalAttributes = true;
collectViewAttributes();
res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
getHostVisibility(), mDisplay.getDisplayId(),
mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
mAttachInfo.mOutsets, mInputChannel);
} catch (RemoteException e) {
mAdded = false;
mView = null;
mAttachInfo.mRootView = null;
mInputChannel = null;
mFallbackEventHandler.setView(null);
unscheduleTraversals();
setAccessibilityFocus(null, null);
throw new RuntimeException("Adding window failed", e);
} finally {
if (restore) {
attrs.restore();
}
}
// ...
}
mWindowSession是IWindowSession类型变量,它是一个Binder对象!
真正的实现者是 Session!
@Override
public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs,
int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInsets,
Rect outOutsets, InputChannel outInputChannel) {
return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId,
outContentInsets, outStableInsets, outOutsets, outInputChannel);
}
这里又通过WindowManagerService来实现window的添加,这样window的添加事务就交给了WMS进行处理!
WindowMangerImpl.java
@Override
public void updateViewLayout(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
applyDefaultToken(params);
mGlobal.updateViewLayout(view, params);
}
public void updateViewLayout(View view, ViewGroup.LayoutParams params) {
// ...
final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams)params;
// 设置新的布局参数
view.setLayoutParams(wparams);
synchronized (mLock) {
int index = findViewLocked(view, true);
ViewRootImpl root = mRoots.get(index);
mParams.remove(index);
mParams.add(index, wparams); // 更新mParams集合对应的值
root.setLayoutParams(wparams, false); // 更新ViewRootImpl中的参数, false表示不是一个新的view
}
}
ViewRooImpl.java
void setLayoutParams(WindowManager.LayoutParams attrs, boolean newView) {
synchronized (this) {
// ...
if (newView) {
mSoftInputMode = attrs.softInputMode;
requestLayout();
}
//...
mWindowAttributesChanged = true;
scheduleTraversals();
}
}
在这个函数里面又调用了scheduleTraversals() 来重新进行测量,布局,绘制流程!
在ViewManager接口中只有一种删除函数:
public void removeView(View view);
但是在WindowManager接口中又增加了一种删除view的方式:
public void removeViewImmediate(View view); // 立即删除
这两种方式,一种表示同步删除,一种表示异步删除!
但是两者都会去调用 WindowManagerGlobal中的 removeView() 函数!
WindowManagerImpl.java
@Override
public void removeView(View view) {
mGlobal.removeView(view, false);
}
@Override
public void removeViewImmediate(View view) {
mGlobal.removeView(view, true);
}
WindowManagerGlobal.java
public void removeView(View view, boolean immediate) {
if (view == null) {
throw new IllegalArgumentException("view must not be null");
}
synchronized (mLock) {
// 查找要被删除view的索引
int index = findViewLocked(view, true);
// 从mRoots这个集合中得到view对象
View curView = mRoots.get(index).getView();
// 执行删除操作
removeViewLocked(index, immediate);
if (curView == view) {
return;
}
throw new IllegalStateException("Calling with view " + view
+ " but the ViewAncestor is attached to " + curView);
}
}
removeView() 第二个参数表示是否立刻删除~
private void removeViewLocked(int index, boolean immediate) {
// 获取view对应的ViewRootImpl对象
ViewRootImpl root = mRoots.get(index);
View view = root.getView();
// ...
// 调用View中的die()函数
boolean deferred = root.die(immediate);
if (view != null) {
view.assignParent(null);
if (deferred) { // 添加到正在被删除的集合中
mDyingViews.add(view);
}
}
}
ViewRootImpl.java
boolean die(boolean immediate) {
// 立刻删除时,直接执行doDie()函数完成真正的删除操作!然后返回false
if (immediate && !mIsInTraversal) {
doDie();
return false;
}
// ...
// 异步删除时,发送一个请求删除的消息,然后直接返回true
mHandler.sendEmptyMessage(MSG_DIE);
return true;
}
其实在异步删除时,handler处理的时候也是调用的doDie()函数来完成删除!
case MSG_DIE:
doDie();
break;
ViewRootImpl.java
void doDie() {
checkThread(); // 检查线程, 很多地方都会调用这个函数!
synchronized (this) {
if (mRemoved) { // mRemoved默认是false,doDie()函数执行时变为true
return;
}
mRemoved = true;
if (mAdded) { // 如果当前window对象应被添加到屏幕上!则需要回调detach函数
dispatchDetachedFromWindow();
}
if (mAdded && !mFirst) {
destroyHardwareRenderer(); // 停止硬件渲染
if (mView != null) {
int viewVisibility = mView.getVisibility();
boolean viewVisibilityChanged = mViewVisibility != viewVisibility;
if (mWindowAttributesChanged || viewVisibilityChanged) { // 如果window属性更改或者显示方式改变
try {
if ((relayoutWindow(mWindowAttributes, viewVisibility, false)
& WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) {
mWindowSession.finishDrawing(mWindow);
}
} catch (RemoteException e) {
}
}
mSurface.release(); // 释放资源
}
}
mAdded = false; // 状态还原
}
WindowManagerGlobal.getInstance().doRemoveView(this);
}
WindowManagerGlobal.java
void doRemoveView(ViewRootImpl root) {
synchronized (mLock) {
final int index = mRoots.indexOf(root);
if (index >= 0) {
mRoots.remove(index);// 从ViewRootImpl集合中删除
mParams.remove(index); // 删除对应的参数
final View view = mViews.remove(index); // 删除对应的view
mDyingViews.remove(view);// 从正在被删除的集合中删除view
}
}
if (ThreadedRenderer.sTrimForeground && ThreadedRenderer.isAvailable()) {
doTrimForeground();
}
}
再来看看dispatchDetachedFromWindow()函数
void dispatchDetachedFromWindow() {
if (mView != null && mView.mAttachInfo != null) {
mAttachInfo.mTreeObserver.dispatchOnWindowAttachedChange(false);
mView.dispatchDetachedFromWindow(); // 回调view的detach函数!方法内部会调用onDetachedFromWidow()函数 和 onDetachedFromWindowInternal()函数
}
// ...
destroyHardwareRenderer();
// ...
mSurface.release();
// ...
try {
mWindowSession.remove(mWindow);
} catch (RemoteException e) {
}
// ...
mDisplayManager.unregisterDisplayListener(mDisplayListener);
unscheduleTraversals();
}
再次通过IPC方式调用remove()函数!
Session.java
public void remove(IWindow window) {
mService.removeWindow(this, window);
}
WMS.java
public void removeWindow(Session session, IWindow client) {
synchronized(mWindowMap) {
WindowState win = windowForClientLocked(session, client, false);
if (win == null) {
return;
}
removeWindowLocked(win);
}
}
void removeWindowLocked(WindowState win) {
removeWindowLocked(win, false);
}
void removeWindowLocked(WindowState win, boolean keepVisibleDeadWindow) {
win.mWindowRemovalAllowed = true;
// ...
boolean wasVisible = false;
// ...
removeWindowInnerLocked(win);
// ...
}
removeWindowInnerLocked(win); 方法内部分析先暂停!!!