IPC架构
应用开发者通过 WindowManager.addView向系统申请一个窗口,App进程内的Framework最终调用WindowManagerGlobal.addView,这里记录了View和窗口参数,还将为View新建一个ViewRoot
root = new ViewRootImpl(view.getContext(), display);
view.setLayoutParams(wparams);
//添加到全局变量
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
try {
//把View记录到ViewRoot的mView中,因为接下来ViewRoot要频繁访问
root.setView(view, wparams, panelParentView);
} catch (RuntimeException e) {
//…
}
- ViewRoot即是View 布局系统的引擎,也是系统窗口管理的对接者
- ViewRoot通过IWindowSession访问WMS
- WMS又通过IWindow反过来访问ViewRoot
在ViewRoot的构造器中:
public ViewRootImpl(Context context, Display display) {
Context = context;
//获取连接
mWindowSession = WindowManagerGlobal.getWindowSession();
//…
//IWindow对象,WMS将通过它管理
mWindow = new W(this);
//…
}
IWindowSession在服务端的实现是Session,ViewRoot.setView调用远程的WindowSession.addToDisplay
class Session extends IWindowSession.Stub{
@Override
public int addToDisplay(IWindow window, …) {
return mService.addWindow(this, window, …);
}
}
ViewRoot通过IWindowSeession.addToDisplay向WMS添加mWindow(W对象,IWindow子类),使WMS也可以访问Window,实现双向通信。
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView)
{
//…
res = mWindowSession.addToDisplay(mWindow, …);
//…
}
调用流程:
wms-relation.png应用和窗口是一对多的关系,所以每个窗口都要和窗口有个独立的seesion
WMS添加窗口
主要成员变量
- mSessions: WindowSession列表,与各窗口通信
- mTokenMap: WindowToken列表,一个token关联一系列有联系的窗口
- mWindowMap: WindowState列表,代表窗口
- mPolicy: 即 PhoneWindowManager
addWindow的具体流程
- 权限检查
- WMS保存一个"窗口-状态"的键值对表,检查是否重复添加
- 如果是子窗口,那么它的父窗口不能也是子窗口
- 根据不同窗口类型,确定是否加WindowToken(窗口令牌)
- 为新增的窗口新建一个WindowState
- 如果客户端死亡,则不再执行
- 窗口参数调整
- 如果新增了WindowToken,添加到全局表
- 重新调整窗口顺序
- 计算窗口大小
- 分配最终层级值
网友评论