《Android开发艺术探索第八章读书笔记》-Window和WindowManager

第八章学习

  1. Window是一个抽象类,它的体实现是PhoneWindow,通过WIndowmanager来创建一个WIndow。WIndowManager是外界访问WIndow的入口,Window具体实现是在WIndowManagerService中,而WindowManager和WindowMangerService的交互式一个IPC过程。Activity、Dialog和Toast是附加在WIndow上的,因此WIndow实际上是VIew的直接管理者。

  2. WindowManager添加一个Window的过程

//将一个Button添加到屏幕坐标为(100,300)的位置上
mFloatingButton = new Button(this);
mFloatingButton.setText("button");
mLayoutParams = new WindowManger.LayoutParams(
LayoutParams.WRAP_Content, LayoutParams.WRAP_CONTENT, 0, 0, PixelFormat.TRANSPARENT
);
mLayoutParams.flags = LayoutParams.FLAG_NOT_TOUCH_MODEL|LayoutParams.FLAG_SHOW_WHEN_LOCKED|LayoutParams.FLAG_SHOW_WHEN_LOCKED;
mLayoutParams.gravity = Gravity.LEFT | Gravity.TOP;
mLayoutParams.x = 100;
mLayoutParams.y = 300;
mWindowManger.addView(mFloatingButton, mLayoutParams);
  1. Flags参数标识WIndow的属性:

    • FLAG_NOT_FOCUSABLE:表示Window不需要获取焦点,也不需要接受各种输入事件,此标记会同时启用FLAG_NOT_TOUCH_MODEL,最终事件会直接传递给下层的具有焦点的Window
    • FLAG_NOT_TOUCH_MODAL:在此模式下,系统会将当前Window区域以外的单击事件传递给底层的Window,当前Window区域以内的单击事件则自己处理。一般都需要开启此标记,否则其他Window将无法收到单击事件
    • FLAG_SHOW_WHEN_LOCKED:开启此模式可以让Window显示在锁屏的界面上
  2. Type参数表示Window的类型:

    • 三种类型分别为应用Window、子Window和系统Window。
    • 子Window不能单独存在,它需要附属在特定的父Window中(Dialog)。系统Window是需要声明去权限才能创建Window(Toast状态栏)
    • Window是分层的,每个Window都有对应的z-ordered。层级大的会覆盖在层级小的Window的上面。而应用Window的层级范围是1~99,子Window的层级范围是1000~1999,系统Window的层级范围是2000~2999,这些层级范围对应着Windowmanager.LayoutParams的type参数
    • WindowManager提供了三个方法:添加View/更新View和删除View

Windiw的内部机制

在实际使用中无法直接访问WIndiw,对Window的访问必须通过WindowManager。

  1. WIndow的添加过程
    Window的添加过程实现添加过程的是WindowManagerImpl类,但它也没有直接实现WIndow的三大操作,而是全部交给了WIndowManagerGlobal来处理。添加过程最终由ViewRootImpl的setView方法完成,之后setView内部会通过requestLayout来完成一部数显请求,之后调用WindowSession来完成Window的添加过程。Window的添加过程是一次IPC调用
  2. Window的删除过程
    有两种删除方式异步删除和同步删除。真正删除View的逻辑是在doDie方法内部会调用dispatchDetachedFromWindow方法的内部实现。
  3. WIndow的更新过程
    会调用updateViewlayout方法,在ViewRootImpl中会通过scheduleTraversals方法来对View重新布局,包括测量、布局和重绘三个过程、它同样是一个IPC过程

Window的创建过程

  1. Activity的WIndow的创建过程
    Activity将具体实现交给了Window处理,而Window的具体实现时PhoneWIndow.
    • DecorView的创建工行才能有installDector方法来实现,在方法内部会通过generateDecor方法来直接创建DecorVIew,之后PhoneWindow需要通过generateLayout方法来加载具体的布局文件到DecorView中。
    • 初始完成了DecorView之后,将Activity的布局文件添加到DecorView里面,在这里Activity的布局文件只是被添加到DecorView的mContentParent中
    • 之后回调Activity的onContentChanged方法通知Activity视图发生改变
    • 最后一步,在ActivityThread的handleResumeActivity方法中,调用Activity的onResume方法,接着会调用Activity的makeVisible(),也正是在makeVisible方法中,DecorView真正完成了添加和显示着两个过程。
  2. Dialog的Window创建过程
    • 过程与Activity的Window创建过程类似,普通的Dialog的有一个特别之处,即它必须采用Activity的Context,如果采用Application的Context会报错。原因是Application没有应用token,应用token一般是Activity拥有的。[service貌似也有token?]
  3. Toast的Window创建过程
    • Toast是基于Window来实现的,但是由于Toast具有定时取消这一功能吗,所以系统刚才用了Handler。其中有两类IPC过程,一类是Toast访问NotificationManagerService,第二类是NotificationManagerService回调Toast里的TN接口。
    • Toast属于系统Window,内部的视图由两种方式指定,一种是系统默认的样式,另一种是通过setView方法来指定一个自定义View.
    • 显示和隐藏都需要通过NMS来实现,而它都是通过远程调用的方式来显示和隐藏Toast,这里要用到Handler将其切换到当前线程,所以Toast无法再没有Looper的线程中弹出。
    • 在NMS的enqueToast方法中,将Toast请求封装为ToastRecord对象并将其添加到一个名为mToastQueue的队列中。最多同时存在50个ToastRecoed.
    • 显示和隐藏都是一次IPC过程
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值