Window: View 的直接管理者。
WindowManager :是一个接口,实现类是WindowManagerImpl
WindowManager和 WindowManangerService 的交互是IPC过程
Window:
flags:控制window的显示特性
FLAG_NOT_FOCUSABLE: 表示window不需要获取焦点,也不需要接收各种输入
事件。此标记会同时启用FLAG_NOT_TOUCH_MODAL。最终事件会传递给
下层的 具有焦点的window
FLAG_NOT_TOUCH_MODAL:系统会将当前window区域以外的单击事件传递给
底层的window.当前区域以内的单击事件自己处理。一般会开启
FLAG_SHOW_WHEN_LOCLED:可以让window显示在锁屏界面上
type:表示window的类型(层级大的Window会覆盖在层级小的Window上面)
应用Window: Activity
子Window:Dialog
系统Window:Toast, 系统状态栏
系统层级常用:TYPE_SYSTEM_OVERLAY,TYPE_SYSTEM_ERROR
例如:步骤一:mLayoutParams.type = LayoutParams.TYPE_SYSTEM_ERROR
步骤二:声明系统权限(android.permission.SYSTEM_ALERT_WINDOW)
Window内部机制:
WindowManagerImpl 委托 WindowManagerGlobal 实现 添加,删除,更新。每次操作都是一次IPC过程。
添加:1.检查参数是否合法
2.创建ViewRootImpl,并将View添加到列表中
3.ViewRootImpl更新界面并完成Window的添加过程(mWindowSession是Binder
对象,Window添加过程是一次IPC调用,Session 通过 WindowManagerService
添加Window,每个应用保留一个单独的Session)
删除:数组遍历,查找删除的View索引
removeViewImmediate:同步删除
removeView:异步删除(常用)
(异步删除 发送MSG_DIE消息,ViewRootImpl 中的Handler会处理此消息,调用doDie()
同步删除 不发消息,直接调用doDie())
dispatchDetachedFromWindow():
1.垃圾回收相关工作,比如清楚数据和消息,移除回调
2.通过Session的 remove 方法删除Window:这同样是一个IPC过程,最终会
调用WindowManagerService的 removeWindow方法
3.调用View 的dispathDetachedFromWindow方法,内部会调用View的 onDeatachedFromWindow()以及
onDetachedFromWindowInternal()。onDetachedFromWindwo()当View
从Window 中移除时会调用。可以做一些资源回收的工作,例如停止动画,
停止线程等。
4.调用WindowManagerGlobal的 doRemoveView刷新数据,
包括mRoots,mParams,mDyingView都需要将当前Window关联的这三类
对象从列表中删除。
更新:移除老的LayoutParams参数,添加新的LayoutParams参数。
通过ViewRootImpl实现,并通过WindowSession更新Window视图。
调用WindowManagerService的relayWindow(),也是一个IPC过程。
Window的创建过程:
Window 对象的创建是通过PolicyManager的 makeNewWindow方法实现的
Activity:· ·1.如果没有DecorView,那么就创建它
2.将View 添加到DecorView的mContentParent中
3.回调Activity 的 onContentChanged 方法,通知Activity视图已经发生改变
Dialog:····1.创建Window
2.初始化DecorView , 并将Dialog的视图添加到DecorView中
3.将DecorView添加到Window中显示
(普通dialog 有一个特殊之处:那就是必须采用Activity的 Context ,如果采用
Application的会报错“没有应用token” , 而“应用token” 一般只有Activity 拥有。
系统Window比较特殊,不需要token)
Toast: 1.由于 Toast 具有 定时取消 功能,所以系统采用了Handler.
2.Toast内部有两类IPC过程。第一类:Toast 访问 NotificationManagerService ;
第二类 :NotificationManagerService 回调Toast的 TN 接口
3.内部视图指定方式:系统默认 , setView
4.显示和隐藏 Toast 都需要通过NMS ,由于 NMS运行在系统进程,所以只能通过远程调用。TN 是一个Binder类,在Binder线程池中,所以需要Handler 切换到使用Toast的线程,因此无法在没有Looper的线程中弹出。将Toast 请求封装为ToastRecode存放在 mToastQueue (ArrayList ),非系统应用最多50个Toast.