美文网首页Android知识
Dialog 的显示过程分析

Dialog 的显示过程分析

作者: 任教主来也 | 来源:发表于2017-03-01 10:23 被阅读31次

    Tip

    这篇文章是由设计模式中的 Buidler 模式中引出的,由于 AlertDialog 使用了 builder 模式,在分析 Dialog 的过程中,用到的 WindowManager 来完成到屏幕的展示,如果想了解 Builder 模式的可以看 这里

    正文

    在 Dialog 的 show 方法的最后,是通过调用 WindowManager 的 addView 方法将视图最后显示到了屏幕上,接下来就深入了解 addView 方法的工作过程

    其实,不单是 Dialog ,Activity 、Toast 等需要显示到屏幕上的内容,都是通过 WindowManager 完成的。

    WindowManager 在系统注册时会保存 WindowManagerImpl 对象到 ContextImpl 类中的一个静态 Map 中的,使用 Context 的 getSystemService 方法提供单例的对象。

    工作过程

    第一步 WindowManger 的方法

    Dialog 中的 mWindowManager 为 WindowManagerImpl 对象,是全局单例的对象,在 Dialog 的构造函数中初始化 mWindowManager 参数的值,并在 Dialog 的构造函数中创建 Window 对象,Window 对象创建之后,调用其 setWindowManager 方法建立与 WindowManagerImpl 之间的联系

    setWindowManager 中主要完成了根据 Window 对象创建新的与 Window 有联系的 WindowManagerImpl 实例的任务,并为 Window 中的属性 mWindowManager 赋值,在 Java 层上 Window 与 WindowManager 建立了第一步联系。

    mWindowManger = new WindowManagerImpl(mDisplay,window);

    由于 Java 中对象传递为值传递,所以 Dialog 中将 WindowManagerImpl 传递到 Window 对象中进行操作,WindowManagerImpl 对象发生改变,Dialog 中的 WindowManagerImpl 对象也会跟着改变的,所以,在 Dialog 的 show 方法中,最终调用的也是与当前 Window 有关联的 WindowManagerImpl 对象的 addView 方法

    注意:这里是使用单例的 WindowManagerImpl ,通过不同的 Window ,构建了与 Window 有关联的 WindowManagerImpl 对象

    第二步 WindowManagerGlobal 的方法

    在 WindowManagerImpl 中存在一个单例存在的 WindowManagerGlobal 对象,在 WindowManagerImpl 的各个方法中,将任务的执行过程传递到了 WindowManagerGlobal 中,在传递过程中除了将 View、LayoutParams 传递,还将 WindowManagerImpl 中关联的 window 对象也一起传递

    在 WindowManagerGlobal 的 addView 方法中,最后通过 ViewRootImpl 的 setView 将 View 显示,具体过程是与 WindowManagerService 的交互

    ViewRootImpl

    继承自 Handler 类,是作为 native 层和 Java 层 View 系统通信的桥梁

    ViewRootImpl 中保存了当前线程,开发过程中在子线程中更新 UI 会抛出异常,是因为 ViewRootImpl 是 UI 线程中创建的,并不是因为只有 UI 线程才可以更新 UI

    第三步 建立与 WindowManagerService 的联系

    在 ViewRootImpl 的构造方法中,会调用 WindowManagerGlobal 的 getWindowSession 方法获取 IManagerSession 对象

    首先 getWindowManagerService 方法中,通过 ServiceManager.getService("window") 方法获得 IBinder 对象,Android Framework 与 WMS 的通信通过 Binder 机制,再通过 IManagerManager 对象的 Stub 类的 asInterface 函数将 IBinder 转换成 IWindowManager 对象,再通过 IManagerManager 的 openSession 方法来与 WMS 建立一个长期的通信会话,需求都通过 Session 来交换信息

    简述总结一下这个过程,通过 Binder 机制获取 IManagerSession 对象,再通过 IManagerSession 对象来跟 WMS 完成信息的交换

    第四步 ViewRootImpl 的 setView 方法

    在 WindowManagerGlobal 的 addView 方法中,调用 ViewRootImpl 的 setView 方法

    1. requestLayout View 树的 measure layout draw 过程

    2. sWindowSession.add() 方法,向 WMS 发起显示当前 Window 的请求

    相关文章

      网友评论

        本文标题:Dialog 的显示过程分析

        本文链接:https://www.haomeiwen.com/subject/knrqgttx.html