【移动应用开发技术】Android中Window的管理深入讲解_第1页
【移动应用开发技术】Android中Window的管理深入讲解_第2页
【移动应用开发技术】Android中Window的管理深入讲解_第3页
【移动应用开发技术】Android中Window的管理深入讲解_第4页
【移动应用开发技术】Android中Window的管理深入讲解_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

【移动应用开发技术】Android中Window的管理深入讲解

一、理解Android的Window

Window表示一个窗口的概念,是一个抽象的概念,每一个Window都对应一个View和一个ViewRootImpl,Window和View通过ViewRootImpl来建立联系,因此Window并不是实际存在的,它是以View的形式存在。

Android中的每个窗口View都有一个对应的Window,例如Activity、Dialog,在他们初始化的时候就会为其创建对应的PhoneWindow并赋值到其内部的一个引用

window的层级

WindowLayoutParams.setType设置

每个window都有其对应的层级,应用window在1-99,子window在1000-1999,系统window在2000-2999,层级高的会覆盖层级低的

子window必须依赖于父window存在,例如Dialog必须在Activity中弹出,Dialog中的window为子window,Activity中的window为父window

显示系统级别的window需要权限<uses-permissionandroid:name="android.permission.SYSTEM_ALERT_WINDOW"/>

WindowLayoutparams的flags

FLAG_NOT_FOUCSABLEwindow不需要获取焦点,也不需要接收各种输入事件,回同时启用FLAG_NOT_TOUCH_MODAL

FLAG_NOT_TOUCH_MODAL系统会将当前Window区域外的单击事件传递给底层的Window,在当前Window区域内的事件则自己处理

FLAG_SHOW_WHEN_LOCKED开启此模式让window显示在锁屏界面上

二、理解Android中的WindowManager

Android中对Window的管理都是通过WindowManager来完成的,创建PhoneWindow之后还会为该Window对象设置WindowManager,WindowManager是一个接口继承ViewManager接口,从这里也能看出对Window的操作其实就是对View的操作,WindowManager的实现类是WindowMangerImpl,WindowMangerImpl通过new创建。

三、Window与WindowManagerImpl的关联

通过ContextImpl的getSystemService可以得到WindowManagerImpl实例,同一ContextImpl得到的是同一个WindowManagerImpl对象,得到WindowMangerImpl之后,调用Window的setWindowManager方法建立Window与WindowManagerImpl之间的联系。

setWindowManager中主要完成在WindowManagerImpl实例的基础上重新创建一个与当前Window绑定的WindowManagerImpl,并为Window中的属性mWindowManager赋值

也就是说在Java层上Window与WindowManager建立了第一步联系,并将Activity、Dialog等中的WindowManager赋值为新的WindowManagerImpl对象。

注意:这里是使用单例的WindowManagerImpl,结合不同的Window,最后构建了与Window有关联的非单例的WindowManagerImpl对象

四、对

Window的操作

1.添加操作WindowManagerImpl.addView,注意,是添加一个新的Window,不是对一个Window中的view做操作

Android中每显示一个窗口,其实就是将View显示到屏幕的过程,如果我们自定义一个要显示的布局,拿到View对象,这时候只要调用WindowManagerImpl对象的addView方法就行了,通过ContextImpl的getSystemService可以得到WindowManagerImpl实例

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

WindowManagerGlobal的addView方法

WindowMAnagerGlobal中判断view、LayoutParams等参数合法性,创建ViewRootImpl,将ViewRootImpl、View、LayoutParams添加到WindowMAnagerGlobal中对应的ArayyList集合中,再调用ViewRootImpl的setView方法

ViewRootImpl

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

ViewRootImpl创建时保存了创建其的线程的引用,开发过程中更新View时会判断当前线程是否是创建ViewRootImpl的线程,如果不是会抛出异常。

一般都是在主线程中创建ViewRootImpl,所以在子线程更新UI会抛出异常,是因为ViewRootImpl是UI线程中创建的,并不是因为只有UI线程才可以更新UI

在Activity的onResume之前如果在子线程中修改UI是不会抛出异常的,因为在onResume之后才创建ViewRootImpl,这时更新UI需要经过ViewRootImpl来更新,在onResume之前Activity的屏幕并没有显示,修改UI操作只是会修改layout中的UI,并不会调用ViewRootImpl的方法显示到屏幕上。

所以得出结论,只有UI显示到屏幕上之后,在更新UI时就会判断线程是否为创建UI的线程,如果不匹配则抛出异常,在UI没有显示到屏幕上时更新UI是不会进行线程判断的

ViewRootImpl的setView方法:IWindowSessionWindowManagerService

这里是将View显示到屏幕上的关键,是将View从应用进程传递到系统进程然后完成显示的地方。ViewRootImpl中的IWindowSession对象是通过WindowManagerGlobal的静态方法getWindowSession()得到的,该方法中首先通过ServiceManager通过Binder进行IPC得到系统服务WindowsManagerService在应用进程的远程代理,然后通过AIDL通信的方式调用WMS的openSession()方法得到IWindowSession接口的实现类Session类远程代理对象,Session类也是一个Binder所以可以跨进程传递

在Session的远程代理的addToDisplay方法中通过AIDL调用Session的addToDisplay方法将window信息传递到系统进程,然后调用AMS的addWindow方法,AMS最后将Window中的View显示到屏幕上

2.删除操作,是删除一个屏幕上已有的Window

WindowManagerImpl.removeView操作中,先通过findViewLocked查找要删除的View,再通过View找到对应的Window的ViewRootImpl,将View、LayoutParams、ViewRootImpl从相对应的ArrayList中删除,再通过IPC调用Session的remove其中调用WMS的removeWindow方法,在屏幕上移除该Window对应的View

3.更新操作

WindowManagerImpl.updateViewLayout,为view设置新的LayoutParams,通过findViewLocked找到对应ViewRootImpl,删除LayoutParams集合中旧的LayoutParams,在集合原位置加入新的LayoutParams,调用ViewRootImpl的setLayoutParams完成View的重新测量,布局,绘制,最后通过IPC调用Session再调用WMS完成window的更新。

4.添加Window代码

自定义的Window在创建过程中并没有主动的创建Window,而是在显示的时候由系统维护,这里也体现了Window是一个抽象的概念,最终需要处理的还是View

五、用户触摸屏幕事件处理流程

WMS将事件IPC传递到Window,Window中调用其内部的CallBack对象也就是Activity或者Dialog对象或者的方法。最终将事件传递到View,再通过ViewRootImpl将响应以后的View和对应windowIPC提交到WMS完成响应后的展示。

六、常见Window的创建

1.Activity的Window创建过程Activity启动流程中,Activity的attach方法中为window赋值为一个新的PhoneWindow,setContentView将layout传递到PhoneWindow中,PhoneWindow中通过LayoutInflater的inflate方法加载布局View,并添加到PhoneWindow内部的DecorView中,在onResume的时候,调用WindowManager的addView方法将Window中的DecorView通过WMS显示到屏幕上

Activity在创建Window的时候,实现了Window的Callback接口中的方法,在Window收到触摸时,则会回调Callback中的方法将事件传递到Activity中,Activity中会调对应PhoneWindow中的分发方法,PhoneWindow中会调用DecordView中的方法,最终将事件传递到View中。

猜测事件由WMS传递到Window再到Activity再到Window这样多一层Activity的原因是,开发者可以在Activity中处理事件,不一定非要传递到View

2.Dialog的Window创建过程

同Activity,实例化Dialog对象时创建PhoneWindow,show方法调用时通过AIDL调用WMS的addView方法将View添加到屏幕

3.Toast的Window创建过程

Toast在创建过程中并没有主动的创建Window,而是在显示的时候由系统维护Toast的window,这里也体现了Window是一个抽象的概念,最终需要处理的还是View

Toast的工作工程需要TNNMSWMS三个部分协同完成,IN也是一个Binder,NMS中调用TN是远程访问,TN调用WMS也是远程调用

NMS即NotificationManagerService

Toast的工作过程分为两步七、总结屏幕展示的每一个window,都需要window和View两个相互结合,屏幕中可以有多个Window。以下所说的View都是一个Window中包含的根View

window的创建以及对View的添加,删除、更新是由WindowManager来实现的,而WindowManager中对window的操作通过每个window对应的ViewRootImpl中通过

IPC远程请求IWindowSession中的方法再调用WMS的对应方法将对当前window操作的实现到屏幕上。

每一个Window都对应一个ViewRootImpl,window通过对应的ViewRootImpl来完成对view的管理

在屏幕有用户交互的时候,WMS又会将事件传递到相应界面的Window,Window会调用当前界面的对应的CallBack来处理事件

WindowManager是接口,实现类是WindowManagerImpl,WindowManagerI

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论