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

文章目录

    • 8.1 Window和WindowManager
    • 8.2 Window 的内部机制
      • 8.2.1 Window 的添加过程
    • 8.3 Window 创建过程
      • 8.3.1 Activity 的 Window 创建过程
      • 8.3.2 Dialog 的 Window 创建过程
      • 8.3.3 Toast 的 Window 创建过程

  1. Window 表示一个窗口的概念,是一个抽象类,具体实现是 PhoneWindow,通过 WindowManager 创建,WindowManager 是外界访问 Window 的入口,Window 具体实现位于 WindowManagerService 中,WindowManager 和 WindowManagerService 交互是IPC过程,所有视图都是通过 Window 呈现的,Window是 View 的直接管理者。

8.1 Window和WindowManager

Button button = new Button(this);
button.setText("button");
WindowManager.LayoutParams params = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT, 0, 0,
                PixelFormat.TRANSPARENT);
//window 显示特性
//FLAG_NOT_FOCUSABLE 不能获取焦点
//FLAG_NOT_TOUCH_MODAL 将意外点击事件,传递给底层Window
//FLAG_SHOW_WHEN_LOCKED 显示在锁屏界面上              
params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
params.gravity = Gravity.LEFT | Gravity.TOP;
params.x = 100;
params.y = 300;
WindowManager windowManager = getWindowManager();
windowManager.addView(button, params);
  1. Window 三种类型
类型 简介 层级
应用Window 对应一个Activity 1-99
子Window Dialog等 1000-1999
系统Window 需要权限,比如 Toast和系统状态栏 2000-2999
  1. 一般使用
params = LayoutParams.TYPE_SYSTEM_ERROR
<user-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"
  1. 提供功能
public interface ViewManager
{
   addView();
   updateViewLayout();
   removeView();
}

8.2 Window 的内部机制

  1. Window 对应一个 View 和一个 ViewRootImpl,Window 和 View 通过 ViewRootImpl 来建立联系。

8.2.1 Window 的添加过程

  1. 通过 WindowManager 的 addView 来实现,WindowManager 是一个接口,真正实现通过 WindowManagerImpl 类(WindowManagerGlobal–使用桥接模式)。
  2. addView 过程
1.检查参数合法,子 Window 还需要调整布局参数
2.创建 ViewRootImpl并将View添加到列表中
3.通过 ViewRootImpl 来更新界面并且完成 Window的添加过程(IPC 调用) 

ViewRootImpl(setView) -> requestLayout(scheduleTraversals)-> WindowSession(是IWindowSession,一个 Binder对象,真正实现 Session,添加过程是一次 IPC 调用过程)
  1. removeView 过程
WindowManagerGlobal->removeView(findViewLocked)->ViewRootImpl来完成删除操作。
1.removeView 异步删除 die 方法 并没有马上删除,添加到 mDyingViews 中
2.removeViewImmediate 同步删除
3.删除逻辑 dispatchDetacheFromWindow 中
3.1.垃圾回收,清除数据、回调
3.2.Session的remove删除Window,IPC 过程
3.3.View 的 dispatchDetachedFromWindow,资源回收(终止动画、停止线程)
3.4.WindowManagerGlobal的doRemoveView 方法刷新数据。
  1. updateViewLayout 过程
WindowManagerGlobal->updateViewLayout()
1.更新 View 的 LayoutParams 替换老的 LayoutParams
2.更新 ViewRootImpl中的 LayoutParams(setLayoutParams)
3.sheduleTracersals 对View 重新布局(测量、布局、绘制)
4.WindowSession更新Window视图
5.WMS的relayoutWindow具体实现,IPC 过程。

8.3 Window 创建过程

  1. View 是 Android 中视图呈现方式,不能单独存在,必须依附 Window上。

8.3.1 Activity 的 Window 创建过程

  1. Activity启动过程 最终由 ActivityThread 中的 performLauncherActivity() 来完成(通过类加载器来创建 Activity 实例对象,并调用 attach 方法关联运行过程中依赖的上下文环境变量)。
1.Activity中的 attach中,创建 Window对象(PolicyManager的makeNewWindow->new PhoneWindow()),并且设置回调。
2.setContentView->getWindow().setContentView()
3.步骤
3.1.如果没有 DecorView,就创建
3.2.将View添加到DecorView的mContentParent中
3.3.回调Activity的onContentChanged方法通知Activity视图发生改变。
3.4.ActivityThread的handleResumeActivity会调用Activity的onResume,调用 makeViesible(),DecorView 显示出来了

8.3.2 Dialog 的 Window 创建过程

  1. 类似,但是 Context 必须是 Activity

8.3.3 Toast 的 Window 创建过程

  1. 具有定时取消,系统采用 Handler,有两类 IPC(NotificationManagerService、NotificationManagerService回调 Toast 的 TN (Binder类)接口)
  2. mToast 最多同时存在 50 个 ToastRecord

你可能感兴趣的:(读书笔记,#,Android开发艺术探索)