Android Framework 之 Window / WindowManager基本概念及addView源码分析

Posted 小陈乱敲代码

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android Framework 之 Window / WindowManager基本概念及addView源码分析相关的知识,希望对你有一定的参考价值。

WMS(WindowManagerService) 是Framework一个重要的概念.
先从Window/WindowManager 理解入手,后续在进一步了解WMS.

1. Window 概念

1.1 Window 是一个抽象的 窗口概念

Activity/Dialog /Toast 的视图(View) 都是附加到Window上 。
可以这么说, android 上的一切视图即我们看到的, 都是通过 Window 呈现出来的.

1.2 Window 同时又是一个抽象类

它是 顶级窗口外观行为策略 的抽象基类。
实现类为PhoneWindow(有且仅有这个实现类)。

从源码上看,
(1) 它定义了 Window 状态变化的回调接口 (按键事件/ focus / attached).
(2) 保存一个 mWindowManager 对象,因为View的管理最终依赖WindowManager实现.

外接通过创建 PhoneWindow 实例,然后获取 WindowManager实例对象,
最后调用 Window.setWindowManager 设置给Window本身 (如果传递wm为空也会重现获取一个.)

package android.view;

public abstract class Window 

    public interface Callback 
        public boolean dispatchKeyEvent(KeyEvent event);
        public boolean dispatchTouchEvent(MotionEvent event);
        public void onWindowAttributesChanged(WindowManager.LayoutParams attrs);
        public void onContentChanged();
        public void onWindowFocusChanged(boolean hasFocus);
        public void onAttachedToWindow();
        public void onDetachedFromWindow(); 
    
    
     public interface OnWindowDismissedCallback 
        void onWindowDismissed(boolean finishTask, boolean suppressWindowTransition);
    
    
        /** @hide */
    public interface WindowControllerCallback 
        void updateStatusBarColor(int color);
        void updateNavigationBarColor(int color);   
    
    
    public void setWindowManager(WindowManager wm, IBinder appToken, String appName,
            boolean hardwareAccelerated) 
        mAppToken = appToken;
        mAppName = appName;
        ...
        if (wm == null) 
            wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
        
        mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);
    
    
    public void setFlags(int flags, int mask) 
       ...
    


(3) 定义设置、获取视图 : DecorView(顶级) / 状态栏颜色 / 导航栏背景

   public abstract void setContentView(@LayoutRes int layoutResID);
    public abstract @NonNull View getDecorView();

   public abstract void setNavigationBarColor(@ColorInt int color);
   public abstract void setStatusBarColor(@ColorInt int color);
    public abstract int getStatusBarColor();
    public abstract int getNavigationBarColor();

1.3 Activity 中的DecorView, Dialog 中的 View(DecorView) 都是在PhoneWindow 中创建.

所以,Window 是View的直接管理者。

package com.android.internal.policy;

public class PhoneWindow extends Window implements MenuBuilder.Callback 
           private DecorView mDecor;

          public PhoneWindow(@UiContext Context context, Window preservedWindow,
            ActivityConfigCallback activityConfigCallback) 
                if (preservedWindow != null) 
                    mDecor = (DecorView) preservedWindow.getDecorView();
                
          
         private void installDecor() 
              mForceDecorInstall = false;
              if (mDecor == null) 
                    mDecor = generateDecor(-1);
                ..............
         


例如,Activity收到点击时间后,通过Window将事件传递给DecorView,再分发给我们自己的view(事件分发机制)

1.1 Window 进一步介绍

每个Window 对应一个View 和ViewRootImpl.
ViewRootImpl 作为 Window 和 View的桥梁。
(实际上Window是不存在的,以View的形式表示,即View是实体)

2. WindowManager 概念

ViewManager接口定义了 添加、更新、删除View 的三个方法。

/** Interface to let you add and remove child views to an Activity. To get an instance
  * of this class, call @link android.content.Context#getSystemService(java.lang.String) Context.getSystemService().
  */
public interface ViewManager

    public void addView(View view, ViewGroup.LayoutParams params);
    public void updateViewLayout(View view, ViewGroup.LayoutParams params);
    public void removeView(View view);



WindowManager 接口 继承 ViewManager.

@SystemService(Context.WINDOW_SERVICE)
public interface WindowManager extends ViewManager 

因此,它实际上是操作Window 中的View.

它的操作是通过它的实现类 WindowManagerImpl/WindowManagerGlobal(最终实现)

2.1 WindowManagerGlobal

有几个重要的成员变量:

    @UnsupportedAppUsage
    private final ArrayList<View> mViews = new ArrayList<View>();
    @UnsupportedAppUsage
    private final ArrayList<ViewRootImpl> mRoots = new ArrayList<ViewRootImpl>();
    @UnsupportedAppUsage
    private final ArrayList<WindowManager.LayoutParams> mParams =
            new ArrayList<WindowManager.LayoutParams>();

其中,
mView 表示每个已添加的View
mRoot 表示每一个ViewRootImpl
mParams 表每一个 布局参数

因此,在addView 添加View 的时候,会把当前view对应的三个参数保存起来

    public void addView(View view, ViewGroup.LayoutParams params,
            Display display, Window parentWindow, int userId) 
            
        final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
        
        root = new ViewRootImpl(view.getContext(), display);

        view.setLayoutParams(wparams);

        mViews.add(view);
        mRoots.add(root);
        mParams.add(wparams);

至于最后的完成添加Window的过程,是通过ViewRootImpl.setView
然后再通过 IWindowSession (Binder) IPC 通信,由WindowManagerService(System_server进程)完成.(因此, ViewRootImpl 负责WMS交互 )
(app 进程(android.view) -> system_server进程)

链接:https://juejin.cn/post/7076274407416528909#heading-25
作者:行走中的3卡

最后

如果你想要深入系统的学习Android Framework框架,这里可以分享一份《Android Framework源码开发揭秘》,其中记录了从系统启动流程到WMS全部源码解析,相信你能优秀地学习整个Framework框架。

因文章篇幅原因,只放了部分内容,完整版扫码免费领取~

第一章 系统启动流程分析

  • 第一节 Android启动概览
  • 第二节 init.rc解析
  • 第三节 Zygote
  • 第四节 面试题

第二章 跨进程通信IPC解析

  • 第一节 Sercice 还可以这么理解
  • 第二节 Binder基础
  • 第三节 Binder应用
  • 第四节 AIDL应用(上)
  • 第五节 AIDL应用(下)
  • 第六节 Messenger原理及应用
  • 第七节 服务端回调
  • 第八节 获取服务(IBinder)
  • 第九节 Binder面试题全解析

第三章 Handler源码解析

  • 第一节 源码分析
  • 第二节 难点问题
  • 第三节 Handler常问面试题

第四章 AMS源码解析

  • 第一节 引言
  • 第二节 Android架构
  • 第三节 通信方式
  • 第四节 系统启动系列
  • 第五节 AMS
  • 第六节 AMS 面试题解析

第五章 WMS源码解析

  • 第一节 WMS与activity启动流程
  • 第二节 WMS绘制原理
  • 第三节 WMS角色与实例化过程
  • 第四节 WMS工作原理

第六章 Surface源码解析

  • 第一节 创建流程及软硬件绘制
  • 第二节 双缓冲及SurfaceView解析
  • 第三节 Android图形系统综述

第七章 基于Android12.0的SurfaceFlinger源码解析

  • 第一节 应用建立和SurfaceFlinger的沟通的桥梁
  • 第二节 SurfaceFlinger的启动和消息队列处理机制
  • 第三节 SurfaceFlinger 之 VSync(上)
  • 第四节 SurfaceFlinger之VSync(中)
  • 第五节 SurfaceFlinger之VSync(下)

第八章 PKMS源码解析

  • 第一节 PKMS调用方式
  • 第二节 PKMS启动过程分析
  • 第三节 APK的扫描
  • 第四节 APK的安装
  • 第五节 PKMS之权限扫描
  • 第六节 静默安装
  • 第七节 requestPermissions源码流程解析

第九章 InputManagerService源码解析

  • 第一节 Android Input输入事件处理流程(1)
  • 第二节 Android Input输入事件处理流程(2)
  • 第三节 Android Input输入事件处理流程(3)

第十章 DisplayManagerService源码解析

  • 第一节 DisplayManagerService启动
  • 第二节 DisplayAdapter和DisplayDevice的创建
  • 第三节 DMS部分亮灭屏流程
  • 第四节 亮度调节
  • 第五节 Proximity Sensor灭屏原理
  • 第六节 Logical Display和Physical Display配置的更新


各位小伙伴们如果有需要这份《Android Framework源码开发揭秘》资料,点击下方卡片即可【免费领取】

以上是关于Android Framework 之 Window / WindowManager基本概念及addView源码分析的主要内容,如果未能解决你的问题,请参考以下文章

android之Framework问题总结:

Android Framework 之启动 ServiceManager

Android 进阶——系统启动之Framework 核心ActivitityManagerService服务启动

Android 进阶——系统启动之Framework 核心ActivitityManagerService服务启动

Android 进阶——系统启动之Framework 核心ActivitityManagerService服务启动

android framework系统源码分析之dumpsys原理分析-千里马带你学framework