- 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);
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);
- Window 三种类型
类型 | 简介 | 层级 |
---|
应用Window | 对应一个Activity | 1-99 |
子Window | Dialog等 | 1000-1999 |
系统Window | 需要权限,比如 Toast和系统状态栏 | 2000-2999 |
- 一般使用
params = LayoutParams.TYPE_SYSTEM_ERROR
<user-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"
- 提供功能
public interface ViewManager
{
addView();
updateViewLayout();
removeView();
}
8.2 Window 的内部机制
- Window 对应一个 View 和一个 ViewRootImpl,Window 和 View 通过 ViewRootImpl 来建立联系。
8.2.1 Window 的添加过程
- 通过 WindowManager 的 addView 来实现,WindowManager 是一个接口,真正实现通过 WindowManagerImpl 类(WindowManagerGlobal–使用桥接模式)。
- addView 过程
1.检查参数合法,子 Window 还需要调整布局参数
2.创建 ViewRootImpl并将View添加到列表中
3.通过 ViewRootImpl 来更新界面并且完成 Window的添加过程(IPC 调用)
ViewRootImpl(setView) -> requestLayout(scheduleTraversals)-> WindowSession(是IWindowSession,一个 Binder对象,真正实现 Session,添加过程是一次 IPC 调用过程)
- 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 方法刷新数据。
- updateViewLayout 过程
WindowManagerGlobal->updateViewLayout()
1.更新 View 的 LayoutParams 替换老的 LayoutParams
2.更新 ViewRootImpl中的 LayoutParams(setLayoutParams)
3.sheduleTracersals 对View 重新布局(测量、布局、绘制)
4.WindowSession更新Window视图
5.WMS的relayoutWindow具体实现,IPC 过程。
8.3 Window 创建过程
- View 是 Android 中视图呈现方式,不能单独存在,必须依附 Window上。
8.3.1 Activity 的 Window 创建过程
- 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 创建过程
- 类似,但是 Context 必须是 Activity
8.3.3 Toast 的 Window 创建过程
- 具有定时取消,系统采用 Handler,有两类 IPC(NotificationManagerService、NotificationManagerService回调 Toast 的 TN (Binder类)接口)
- mToast 最多同时存在 50 个 ToastRecord