最全Android Framework底层原理——WMS机制_android wms 机制流程,2024年最新高级程序员面试题

文末

好了,今天的分享就到这里,如果你对在面试中遇到的问题,或者刚毕业及工作几年迷茫不知道该如何准备面试并突破现状提升自己,对于自己的未来还不够了解不知道给如何规划,可以来看看同行们都是如何突破现状,怎么学习的,来吸收他们的面试以及工作经验完善自己的之后的面试计划及职业规划。

这里放上一部分我工作以来以及参与过的大大小小的面试收集总结出来的一套进阶学习的视频及面试专题资料包,主要还是希望大家在如今大环境不好的情况下面试能够顺利一点,希望可以帮助到大家

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

WMS启动流程
  • WMS启动流程

WMS流程分析

Window添加View
  • 先看一个简单的案例。在主屏幕上添加一个TextView并展示,并且这个TextView独占一个窗口。
TextView mview = new TextView(context);
WindowManager mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams wmParams = new WindowManager.LayoutParams();
wmParams.type = WindowManager.LayoutParams.TYPE_TOAST;
wmParams.width = 800;
wmParams.height = 800;
mWindowManager.addView(mview, wmParams);

  • 对Window添加View的流程步骤分析
    • WindowManager.addView添加窗口之前,TextView的onDraw不会被调用,也就说View必须被添加到窗口中,才会被绘制。只有申请了依附窗口,View才会有可以绘制的目标内存。
    • 当APP通过WindowManagerService的代理向其添加窗口的时候,WindowManagerService除了自己进行登记整理,还需要向SurfaceFlinger服务申请一块Surface画布,其实主要是画布背后所对应的一块内存,只有这一块内存申请成功之后,APP端才有绘图的目标,并且这块内存是APP端同SurfaceFlinger服务端共享的,这就省去了绘图资源的拷贝。
    • APP端是可以通过unLockCanvasAndPost直接同SurfaceFlinger通信进行重绘的,就是说图形的绘制同WMS没有关系,WMS只是负责窗口的管理,并不负责窗口的绘制。
WMS核心职责
  • 窗口管理:
    • WMS是窗口的管理者,负责窗口的启动,添加和删除,另外窗口的大小也时有 WMS 管理的,管理窗口的核心成员有 DisplayContent,WindowToken 和 WindowState
  • 窗口动画:
    • 窗口间进行切换时,使用窗口动画可以更好看一些,窗口动画由 WMS 动画子系统来负责,动画的管理系统为 WindowAnimator
  • 输入系统的中转站:
    • 通过对窗口触摸而产生的触摸事件,InputManagerServer(IMS) 会对触摸事件进行处理,他会寻找一个最合适的窗口来处理触摸反馈信息,WMS 是窗口的管理者,因此理所当然的就成为了输入系统的中转站。
  • Surface管理:
    • 窗口并不具备绘制的功能,因此每个窗口都需要有一个块 Surface 来供自己绘制,为每个窗口分配 Surface 是由 WMS 来完成的。
WMS是如何启动
  • WMS 是在 SystemServer 内部启动的
    • Android 系统在启动的时候,会启动两个重要的进程,一个是 Aygote 进程,两一个是由 Zygote 进程 fork 出来的 system_server 进程,SystemServer 会启动我们在系统中所需要的一系列 Service。
  • 在SystemServer#startOtherServices方法中
    • 核心1:SystemServer#WindowManagerService.main,传入了 IMS,因为 WMS 是 IMS 的中转站。观察 WindowManagerService.main 方法可以知道他是运行在 SystemServer 的 run 方法中,换句话说就是运行在 system_server 线程中。
    • 核心2:SystemServer#ServiceManager.addService,将 WMS 和 IMS 注册到 ServerManager 里面,这样客户端想要使用 WMS 就需要先去 ServiceManager 中查询信息,然后与 WMS 所在的进程建立通信,这样客户端就可以使用 WMS 。
WMS构造方法
  • 在WindowManagerService#main方法中

    • 通过 DisplayThread 的 getHandler 方法获取到了 DisplayThread 的 Handler 实例。用来处理需要低延时显示的相关操作,runWithScissors 表达式中创建了 WMS 对象。
  • 在WindowManagerService#WindowManagerService()构造方法中

    • 初始化 WindowManagerPolicy ,它用来定义一个窗口测量所需要遵循的规范。
    • 创建了 WindowAnimator,它用于管理所有的窗口动画。
    • 创建 RootWindowContainer 对象,根窗口容器。
    • 获取 DisplayManager 服务。
    • 获取 AMS,并持有他的引用。
  • WMS的启动中WMS创建完成后会调用 wm.onInitReady 方法

    • 和 WMS 的 main 方法类似,WindowManagerPolicy (简称 WMP) 是一个接口,init 的具体实现在 PhoneWindowManager(PWM) 中
    • init 方法运行在 android.ui线程中。因此他的线程优先级要高于 android.display 线程,必须等 init 方法执行完成后,android.display线程才会被唤醒从而继续执行下面的代码。
WMS窗口管理
  • Window 的操作有两大部分,一部分是 WindowManager 来处理,一部分是 WMS 来处理
  • 先看第一部分WindowManager处理逻辑
    • WindowManager 中,通过 WindowManagerGlobal 创建 ViewRootImpl ,也就是 View 的根。
    • 在 ViewRootImpl 中完成对 View 的绘制等操作,然后通过 IPC 获取到 Session,最终通过 WMS 来进行处理。
  • 再看第二部分WMS处理逻辑
    • 主要分析是ViewRootImpl#setView()到WindowManagerService.addWindow()的这个过程,涉及到跨进程通信。
    • 1.ViewRootImpl#setView()过程。mWindowSession是IWindowSession对象。在创建ViewRootImpl对象时被实例化。
    • 2.WindowManagerGlobal#getWindowSession()过程。getWindowManagerService()通过AIDL返回WindowManagerService实例。之后调用WindowManagerService#openSession()。
    • 3.WindowManagerService#openSession()过程。返回一个Session对象。也就是说在ViewRootImpl#setView()中调用的是mWindowSession.addToDisplay,其实就是Session#addToDisplay()。
    • 4.Session#addToDisplay()过程。mService是个WindowManagerService对象,也就是说最后调用的是WindowManagerService#addWindow()
    • 5.WindowManagerService#addWindow()过程。mWindowMap是个Map实例,将WindowManager添加进WindowManagerService统一管理。至此,整个添加视图操作解析完毕。
  • 注意WMS并不关心View的具体内容
    • WMS只关心各个应用显示的界面大小,层级值等,这些数据到包含在 WindowManager.LayoutParams 中。

一些源码分析

addView源码分析
  • Window的addView源码分析?
    • WindowManager是一个接口,真正实现类是WindowManagerImpl,并最终以代理模式交给WindowManagerGlobal实现。
    • addView:
      1.创建ViewRootImpl;
      2.将ViewRoot、DecorView、布局参数保存到WM的内部列表中;
      3.ViewRoot.setView()建立ViewRoot和DecorView的联系。
    • setView:
      1.进行View绘制三大流程;
      2.会通过WindowSession完成Window的添加过程(一次IPC调用)
    • requestLayout:内部调用scheduleTraversals(), 底层通过mChoreographer去监听下一帧的刷新信号。
    • mWindowSession.addToDisplay: 执行WindowManagerService的addWindow
    • addWindow: 检查参数等设置;检查Token;将Token、Window保存到WMS中;将WindowState保存到Session中。
remove源码与解析
  • Window的remove源码与解析
    • WindowManager中提供了两种删除接口:removeView异步删除、removeViewImmediate同步删除(不建议使用)
    • 调用WMGlobal的removeView
    • 调用到WMGlobal的removeViewLocked进行真正的移除
    • 执行ViewRoot的die方法():
      1-同步方法直接调用doDie
      2-异步方法直接发送Message
    • doDie(): 调用dispatchDetachedFromWindow()和WindowManagerGlobal.getInstance().doRemoveView(this)
    • dispatchDetachedFromWindow:
      1.回调onDetachedFromeWindow;
      2.垃圾回收相关操作;
      3.通过Session的remove()在WMS中删除Window;
      4.通过Choreographer移除监听器

Android Framework底层原理手册:https://qr18.cn/AQpN4J

  1. 开机Init 进程
  2. 开机启动 Zygote 进程

写在最后

最后我想说:对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们!

这里附上上述的技术体系图相关的几十套腾讯、头条、阿里、美团等公司2021年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。

相信它会给大家带来很多收获:

当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

的技术提升。**

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值