Window底层源码分析(二)

前言

Window底层源码分析(一)中我们只是对Activity从一个组件怎么就管理一个界面的基本的流程去初步了解了一下,其实我们只是知道了一个Window 都是由什么东西组成的,activity是怎么管理的,在什么时候创建的等,那么这篇文章我们就接着上一篇文章继续讨论客户端Window是怎么和服务端WindowManagerService怎么通信的,他们之间的到底是怎么一回事?

WindowManagerService

这里我们就要知道一下WindowManagerService到底只一个什么东西?WindowManagerService和ActivityManagerService一样是一个远程的服务进程,当我们Android系统启动的时候,这些进程都会通过init进程来fork出一个叫zygote的进程,然后他会fork出来一系列的系统服务进程,而WindowManagerService就是其中一个

Window底层源码分析(一)中我们看到了怎么创建初始话界面,但是所有的界面的绘制还是需要交给我们的Android系统去完并且呈现出来的,我们看到每一个窗口其实都是一个surface:

  • Surface是一块画布,应用通过canvas或者openGL在上面作画
  • 作画后通过SurfaceFlinger将多块Surface的内容按照Z-order进行混合并输出到FrameBuffer,从而将Android的页面显示给用户。

每个窗口都有一块Surface用于显示自己的ui,必然需要一个角色对窗口进行统一管理,WindowManagerService就是这么一个管理者,现在我们对WindowManagerService有一个感性的认识。

由于WindowManagerService是一个远程的服务进程,我们是不能直接去使用它的,所以我们只能通过IPC的进程间通信的方式来通知WindowManagerService应该去怎么干。

客户端做了哪些事

直接通过源码查看

ViewRootImpl

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();
                    }
                }

    ...

}

我们会看到一个res的一个int型变量,后面是mWindowSession的方法调用,顾名思义这就是会返回一个一个int的数据然后用于抛出一些异常,其实也就是告诉我们和服务端的操作是不是成功等。下面我们去看看他是如何链接的:

* WindowManagerGlobal*

public static IWindowSession getWindowSession() {
        synchronized (WindowManagerGlobal.class) {
            if (sWindowSession == null) {
                try {
                    InputMethodManager imm = InputMethodManager.getInstance();
                    IWindowManager windowManager = getWindowManagerService();
                    sWindowSession = windowManager.openSession(
                            new IWindowSessionCallback.Stub() {
                                @Override
                                public void onAnimatorScaleChanged(float scale) {
                                    ValueAnimator.setDurationScale(scale);
                                }
                            },
                            imm.getClient(), imm.getInputContext());
                } catch (RemoteException e) {
                    throw e.rethrowFromSystemServer();
                }
            }
            return sWindowSession;
        }
    }

通过getWindowManagerService()方法获取到服务端的WindowManagerService的服务

public static IWindowManager getWindowManagerService() {
        synchronized (WindowManagerGlobal.class) {
            if (sWindowManagerService == null) {
                sWindowManagerService = IWindowManager.Stub.asInterface(
                        ServiceManager.getService("window"));
                try {
                    if (sWindowManagerService != null) {
                        ValueAnimator.setDurationScale(
                                sWindowManagerService.getCurrentAnimatorScale());
                    }
                } catch (RemoteException e) {
                    throw e.rethrowFromSystemServer();
                }
            }
            return sWindowManagerService;
        }
    }

可以看到一个很明显的字眼是Stub.asInterface这就是一个进程间通信的标志呀,然后我们就知道了接下来他是通过windowManager.openSession()这个方法去获取服务端的Session,那么下面就进入到了服务端去查看了:

WindowManagerService


    @Override
    public IWindowSession openSession(IWindowSessionCallback callback, IInputMethodClient client,
            IInputContext inputContext) {
        if (client == null) throw new IllegalArgumentException("null client");
        if (inputContext == null) throw new IllegalArgumentException("null inputContext");
        Session session = new Session(this, callback, client, inputContext);
        return session;
    }

很简单就是得到了一个session。。。穿进去了一些参数而已,没有任何的操作,然后通过使用这个session去调用addToDisplay方法。
* 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);
    }

可以看到下面就要去服务端去调用一个addWindow 的方法了。

现在我们知道了每一个客户端Window 都会有一个叫session 的东西从在并且与服务端建立了一个链接(通过这个session和服务端建立链接),通过调用addWindow方法去进入服务端。

服务端做了哪些事

public int addWindow(Session session, IWindow client, int seq,
            WindowManager.LayoutParams attrs, int viewVisibility, int displayId,
            Rect outContentInsets, Rect outStableInsets, Rect outOutsets,
            InputChannel outInputChannel) {

...

        final WindowState win = new WindowState(this, session, client, token, parentWindow,
                    appOp[0], seq, attrs, viewVisibility, session.mUid,
                    session.mCanAddInternalSystemWindow);


...

}

这个方法传过来了好多的参数,然后通过这些参数去判断是否抛出一些异常,代码就不贴了,然后最主要的一个成员变量的初始化,我们可以看到:WindowState这是保证服务端和客户端的一个通信的主要东西;然后我们可以看到他在openSession的时候传过来了一个callback,他里面其实就是执行了一些通信之间的操作的存根。

总结

到现在我们就可以知道:总的来说,是每个window都会有一个服务端返回的session然后服务端会存在一个WindowState对象,我们可以通过带有session的存根对象去和服务端通信。实现一个IPC的过程。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Windows 2000,原名Windows NT 5.0。它结合了Windows 98和Windows NT 4.0的很多优良的功能/性能与一身,超越了Windows NT的原来含义。   Windows 2000系列分成四个产品:Windows 2000 Professional, Windows 2000 Server, Windows 2000 Advanced Server, Windows 2000 Datacenter Server。 Windows 2000 Professional 是一个商业用户的桌面操作系统,也适合移动用户,是Windows NT Workstation 4.0的升级。Windows 2000 Server和Advanced Server分别是Windows NT Server 4.0及其企业版的升级产品。Windows 2000 Datacenter Server是一个新的品种,主要通过OEM的方式销售,是,支持32个以上的CPU和64GB的内存,以及4个节点的集群服务。 Windows 2000平台包括了Windows 2000 Professional 和Windows 2000 Server前后台的集成,下面仅从五个方面简要地介绍一下它的新特性和新功能。   一、活动目录   Windows 2000 Server在Windows NT Server 4.0的基础上,进一步发展了“活动目录(Active Directory)”。活动目录是从一个数据存储开始的。它采用了类似Exchange Server的数据存储,称为:Extensible Storage Service (ESS)。其特点是不需要事先定义数据库的参数,可以做到动态地增长,性能非常优良。这个数据存储之上已建立索引的,可以方便快速地搜索和定位。活动目录的分区是“域(Domain)”,一个域可以存储上百万的对象。域之间还有层次关系,可以建立域树和域森林,无限地扩展。   在数据存储之上,微软建立了一个对象模型,以构成活动目录。这一对象模型对LDAP有纯粹的支持,还可以管理和修改Schema。Schema包括了在活动目录中的计算机、用户和打印机等所有对象的定义,其本身也是活动目录的内容之一,在整个域森林中是唯一的。通过修改Schema的工具,用户或开发人员可以自己定义特殊的类和属性,来创建所需要的对象和对象属性。   活动目录包括两个方面:一个目录和与目录相关的服务。目录是存储各种对象的一个物理上的容器;而目录服务是使目录中所有信息和资源发挥作用的服务。活动目录是一个分布式的目录服务。信息可以分散在多台不同的计算机上,保证快速访问和容错;同时不管用户从何处访问或信息处在何处,都对用户提供统一的视图。 活动目录充分体现了微软产品的“ICE”,即集成性(Integration),深入性(Comprehensive),和易用性(Ease of Use)等优点。活动目录是一个完全可扩展,可伸缩的目录服务,既能满足商业ISP的需要,又能满足企业内部网和外联网的需要 最近在网上游荡的时候发现msdos和windows 2000的原代码 ,不敢独享,所以分享给大家
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值