Window Manager Service

2018-08-14  本文已影响0人  HillLi

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的构造器中:

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添加窗口

主要成员变量

addWindow的具体流程

  1. 权限检查
  2. WMS保存一个"窗口-状态"的键值对表,检查是否重复添加
  3. 如果是子窗口,那么它的父窗口不能也是子窗口
  4. 根据不同窗口类型,确定是否加WindowToken(窗口令牌)
  5. 为新增的窗口新建一个WindowState
  6. 如果客户端死亡,则不再执行
  7. 窗口参数调整
  8. 如果新增了WindowToken,添加到全局表
  9. 重新调整窗口顺序
  10. 计算窗口大小
  11. 分配最终层级值
上一篇 下一篇

猜你喜欢

热点阅读