Android开发艺术探索八 理解Window 和 WindowManager

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.

        

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值