Android视图体系—理解Window概念

Android的Window类详解 详细地讲了android系统window类的属性与成员函数。 立即下载

前言

在Android视图体系中Window就是一个窗口的概念。Android中所有的视图都是依赖于Window显示的,比如:Activity、Dialog、Toast都是在Window中显示的。

首先来熟悉一下Window的属性。

Window的类型:

  • 应用Window:即Android应用所在的Window,比如Activity对应的Window;
  • 子Windwo:必须依赖于应用Window存在,比如:Dialog;
  • 系统Window:系统级别的Window,比如系统错误窗口、Toast。

Windwo的ZOrder属性,ZOrder主要是在屏幕Z轴的数值,主要用来表示Window的层级,数值大的显示在屏幕上层。其中应用Window的数值范围是199;子Window的数值范围是10001999;系统Window的数值范围是2000~2999。

Window的标志:

Flag描述
FLAG_ALLOW_LOCK_WHILE_SCREEN_ON只要窗口可见,就允许在开启状态上的屏幕上锁屏
FLAG_NOT_FOCUSABLE窗口不需要获取焦点,也不需要接收输入事件,设置的同时FLAG_NOT_TOUCH_MODAL也会被设置
FLAG_NOT_TOUCH_MODAL该窗口只会处理自己区域内的点击事件,区域外的事件将传递给其他窗口
FLAG_NOT_TOUCHABLE窗口不接受任何触摸事件
FLAG_KEEP_SCREEN_ON只要窗口可见,屏幕保持常亮
FLAG_LAYOUT_NO_LIMITS允许屏幕超出窗口之外
FLAG_FULLSCREEN窗口全屏显示,隐藏所有屏幕的装饰窗口
FLAG_SHOW_WHEN_LOCKED窗口可以显示在锁屏窗口中
FLAG_IGNORE_CHEEK_PRESSES当用户的脸贴近屏幕时,不会响应此事件
FLAG_TURE_SCREEN_ON窗口显示是将屏幕点亮

窗口机制

在日常开发中,我们通常接触到关于窗口的类有WindowManager和Window。在查看两者的源码时,可以看到WindowManager是一个接口,Window是一个抽象类。其中WindowManager继承了ViewManager接口,ViewManager中定义了三个方法。

public interface ViewManager
{ 
    public void addView(View view, ViewGroup.LayoutParams params);
    public void updateViewLayout(View view, ViewGroup.LayoutParams params);
    public void removeView(View view);
}

可以看到这三个方法是addView(),updateViewLayout(),removeView(),即添加、更新、删除。也就是说WindowManager对Window有三种操作。通过这个三种操作,我们来探究下Window的机制。

Window、WindowManager、WMS

在探究Window的增、改、删之前,先来看看Window、WindowManager、WMS三者的之间的关系。我们知道WMS是一个系统服务,它主要是关系窗口的。在这三者之间WindowMnager与WMS通过Binder进行通信,其中Window的具体操作由WMS承担。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JZtXBRcD-1605344544409)(E:\Blog\Image\window-windownager-WMS.png)]

Window的机制

添加一个Window

WIndowManager接口的实现类是WindowManagerImpl,我们直接分析WindowManagerImpl。

 public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
        applyDefaultToken(params);
        mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
    }

    @Override
    public void updateViewLayout(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
        applyDefaultToken(params);
        mGlobal.updateViewLayout(view, params);
    }
    @Override
    public void removeView(View view) {
        mGlobal.removeView(view, false);
    }

可以看到WindowManagerImpl实现Window的增、删、改是由一个mGlobal的成员实现的。这个mGlobal是WindowManagerGlobal。继续分析WindowManagerClobal。

public void addView(View view, ViewGroup.LayoutParams params,
            Display display, Window parentWindow) {
        // 1.检查参数
        if (view == null) {
            throw new IllegalArgumentException("view must not be null");
        }
        if (display == null) {
            throw new IllegalArgumentException("display must not be null");
        }
        if (!(params instanceof WindowManager.LayoutParams)) {
            throw new IllegalArgumentException("Params must be WindowManager.LayoutParams");
        }
    	// ...
        ViewRootImpl root;
        View panelParentView = null;

        synchronized (mLock) {
            // ...
            // 2.创建ViewRootImpl
            root = new ViewRootImpl(view.getContext(), display);

            view.setLayoutParams(wparams);

            // 添加View
            mViews.add(view);
            mRoots.add(root);
            mParams.add(wparams);

            // do this last because it fires off messages to start doing things
            try {
                // 3.通过创建ViewRootImpl更新界面
                root.setView(view, wparams, panelParentView);
            } catch (RuntimeException e) {
                // BadTokenException or InvalidDisplayException, clean up.
                if (index >= 0) {
                    removeViewLocked(index, true);
                }
                throw e;
            }
        }
    }

在WindowManagerGlobal的addView()方法中可以分为3部分来看。

第一部分是检查参数,主要检查的是View是否为null,Display是否为null,布局参数是否正确。

第二部分是创建了ViewRootImpl,并且保存了相关对象。这里是保存了ViewRootImpl对象、添加的View对象以及布局参数。

第三部分是通过调用ViewRootImpl的setView()方法完成界面的更新。接下来就是开始了View的工作流程,也就是View的绘制过程。

最后再来看下ViewRootImpl的setView()方法。在setView()方法中可以看到:

public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
     // ...
     res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
                getHostVisibility(), mDisplay.getDisplayId(), mTmpFrame,
                mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
                mAttachInfo.mOutsets, mAttachInfo.mDisplayCutout,mInputChannel,
                mTempInsets);
}

这里的mWindowSession是IWindowSession,这是一个Binder对象。最终通过mWindowSession到达WMS中完成了Window的添加过程。

其中添加的具体过程是发生在WMS中,这里就不在具体分析了。

删除一个Window

Window的删除过程我们直接看WIndowManagerGlobal中的removeView()方法。

public void removeView(View view, boolean immediate) {
    //...
        synchronized (mLock) {
            int index = findViewLocked(view, true);
            View curView = mRoots.get(index).getView();
            removeViewLocked(index, immediate);
            if (curView == view) {
                return;
            }
            //...
        }
    }

可以看到删除View时先是找到View对应的索引,然后交由removeViewLocked()方法执行删除逻辑。

private void removeViewLocked(int index, boolean immediate) {
        ViewRootImpl root = mRoots.get(index);
        View view = root.getView();
        // ...
		boolean deferred = root.die(immediate);
        if (view != null) {
            view.assignParent(null);
            if (deferred) {
                mDyingViews.add(view);
            }
        }
    }

这里可以看出主要交给了ViewRootImpl的die()方法完成接下来的删除流程,其中immediate是表示是否立即删除,为true的时候会立即删除;为false的时候会先加入消息队列中。

boolean die(boolean immediate) {
        if (immediate && !mIsInTraversal) {
            doDie();
            return false;
        }
        // ...
        mHandler.sendEmptyMessage(MSG_DIE);
        return true;
    }
void doDie() {
        checkThread();
        if (LOCAL_LOGV) Log.v(mTag, "DIE in " + this + " of " + mSurface);
        synchronized (this) {
            if (mRemoved) {
                return;
            }
            mRemoved = true;
            if (mAdded) {
                // 1.执行删除
                dispatchDetachedFromWindow();
            }
            //...
        // 2.WindowManagerGlobal中的状态更新
        WindowManagerGlobal.getInstance().doRemoveView(this);
    }

在ViewRootImpl中的die()方法主要是区分是否将Window立即删除,接下来删除工作交给了doDie()。在这里有分为两部分。

第一部分是删除Window这里真正的删除了Window。在这里可以看到进行了各种资源的回收,清理数据。然后通过mWindowSession使用WMS删除Window。

void dispatchDetachedFromWindow() {
        mFirstInputStage.onDetachedFromWindow(); 
        removeSendWindowContentChangedCallback();
        destroyHardwareRenderer();
        setAccessibilityFocus(null, null);
        mView.assignParent(null);
        mView = null;
        mAttachInfo.mRootView = null;
        destroySurface();
        if (mInputQueueCallback != null && mInputQueue != null) {
            mInputQueueCallback.onInputQueueDestroyed(mInputQueue);
            mInputQueue.dispose();
            mInputQueueCallback = null;
            mInputQueue = null;
        }
        if (mInputEventReceiver != null) {
            mInputEventReceiver.dispose();
            mInputEventReceiver = null;
        }
        try {
            // 进入WMS中删除Window
            mWindowSession.remove(mWindow);
        } catch (RemoteException e) {
        }

        // Dispose the input channel after removing the window so the Window Manager
        // doesn't interpret the input channel being closed as an abnormal termination.
        if (mInputChannel != null) {
            mInputChannel.dispose();
            mInputChannel = null;
        }
        mDisplayManager.unregisterDisplayListener(mDisplayListener);
        unscheduleTraversals();
    }

第二部分是在WindowManagerGlobal中删除Window的对象。

private void removeViewLocked(int index, boolean immediate) {
        ViewRootImpl root = mRoots.get(index);
        View view = root.getView();

        if (view != null) {
            InputMethodManager imm = view.getContext().getSystemService(InputMethodManager.class);
            if (imm != null) {
                imm.windowDismissed(mViews.get(index).getWindowToken());
            }
        }
        boolean deferred = root.die(immediate);
        if (view != null) {
            view.assignParent(null);
            if (deferred) {
                mDyingViews.add(view);
            }
        }
    }
更新Window

还是直接看WindowManagerClobal中的更新方法。

public void updateViewLayout(View view, ViewGroup.LayoutParams params) {
    //...
        final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams)params;

        view.setLayoutParams(wparams);

        synchronized (mLock) {
            int index = findViewLocked(view, true);
            ViewRootImpl root = mRoots.get(index);
            mParams.remove(index);
            mParams.add(index, wparams);
            root.setLayoutParams(wparams, false);
        }
    }

这里的逻辑相对比较简单。首先是更新View的布局参数,然后通过ViewRootImpl执行。在setLayoutParams()方法中还会调用mWindowSession的relayoutWindow()方法来通过WMS更新窗口。

Window中存在的联系

在分析Window机制的过程中,我们会发现几个出现频繁的类,他们在实现Window机制中都承担了重要的工作,比如:WindowManager、WindowManagerGlobal、ViewRootImp、WMSl等。那个他们之间有什么联系?这里就直接总结一下。

  • 一个Window对应一个ViewRootImpl,一个WindowManager;
  • WindowManagerGlobal是在App主线程启动时初始化的,也就是一个App进程对应一个WindowManagerGlobal;
  • 每个App进程对应一个Session代理,通过Session实现与WMS的通信;

总结

Window在Android中是一个抽象的概念,我们熟知的实现类是PhoneWindow,在PhoneWindow中我们会看到有DecorView也就是我们常说的顶级View。

那么总结来说,Window就是承载了视图的一个容器,Android中所有的视图都会通过Window来显示。而Window由WMS来管理实现增、删、改。

用limma包进行多组差异表达分析 写在前面:最近在使用limma包进行差异表达分析,参考了网上许多教程都觉得说的云里雾里,很不清楚。经过我自己一段时间非常痛苦的钻研,弄明白了,解决了我的实际需求。于是决定将我的分析经验写下来,分享给需要的人。 首先加载前期预处理好的表达矩阵。(我的原始表达矩阵文件已附在文后,大家有需要可以下载实践) setwd("E://Rworkplace") data<-read.table... 阅读详情

相关推荐

MuJoCo新手必看:5分钟搞定你的第一个机器人仿真(附Python代码)

本文为零基础新手提供了一份详尽的MuJoCo物理仿真引擎入门指南。从环境搭建、MJCF模型文件解析,到编写Python控制代码,手把手教你5分钟内创建并运行第一个机器人仿真。内容涵盖双摆模型控制与自定义四轮小车构建,帮助你快速掌握这一高性能开源工具,迈出机器人学与强化学习仿真的第一步。

weixin_29032489的博客 655

Android:Window相关理解

有关Window的相关理解

qjyws的博客 2524

elmos 524系列芯片笔记

芯片的工作工作原理:集成芯片Elmos524.03有发射回路和接收回路,手册有关的内部原理图,大致如下: 芯片会产生固有频率的电压信号,信号通过引脚DRV1、2输出给外部压电陶瓷片,产生固定频率的机械波,也就是所谓的超声波,超声波遇到障碍物时会反射,反射信号经过AINS、D引脚进入芯片,在芯片内部先后经过GAIN放大,滤波然后进入比较器,滤波后的信号(signal)同预先设定的阈值(threshold)比较产生信号输出。此信号最终会连接MCU处理器,需要重点关注。 基于这个内部的工作原

qq_38230916的博客 2484

【Android】Window 机制

Window,即窗口,在 Android 中,它是一个抽象的东西,我们在日常开发中,直接接触到的东西是 View,而 View 是附着在 Window 之上的。所以我们也可以说 Window 是 View 的直接管理者。在了解 window 机制之前,我们需要对 Android 系统中的显示部分涉及到的东西有一个大致的了解。

yang553566463的博客 2408

海康工业相机 Could not find module MvCameraControl.dll(已解决)

【代码】海康摄像机 Could not find module MvCameraControl.dll(已解决)

hmbbpdx的博客 2223

01 Python学习总结:Python简介及入门

Python 是一门高级编程语言,以其简洁、易读和强大的功能而广受欢迎。它适用于多种应用场景,包括 Web 开发、数据分析、人工智能、自动化脚本等。以下是 Python 的简介及入门知识总结,帮助你快速了解并开始学习 Python。

数据知道的博客 1万+

Android Window

Window,即窗口,在 Android 中,它是一个抽象的东西,我们在日常开发中,直接接触到的东西是 View,而 View 是附着在 Window 之上的。所以我们也可以说 Window 是 View 的直接管理者。

liuning1985622的博客 1146

SAP_SD模块更改销售订单定价简介

方式优点缺点适用场景MASS简单,无需开发不能触发重新定价逻辑修改特定字段BDC (VA02)可模拟人工操作维护复杂,速度慢少量订单批改稳定、安全需ABAP支持推荐用于批量重新定价VBOF标准重算返利仅适返利类条件返利更新通过本文,我们了解了 SAP 的[SAP_SD模块更改销售订单定价]的基本概念和应用方法。希望这些信息能帮助您在实际工作中更好地使用 SAP 系统,提高工作效率和管理水平。更多SAP文章请点击更多SAP文章更新,大家一起学习进步!!!

我小时候很黑的博客 712

【15】Android基础知识之Window(一)

window的创建、管理、关联

mr_zengkun的博客 1546

23、电生理与CSD分析:探索大脑活动的前沿技术

本文介绍了电生理与电流源密度(CSD)分析在探索大脑活动中的前沿应用。从电生理技术的发展现状,到局部场电位(LFPs)的起源与解释,重点阐述了CSD分析的原理、实验方法及其在绘制皮层兴奋流、解析突触输入和研究自发振荡中的广泛应用。文章还总结了该领域的优势与挑战,并展望了技术改进、多模态融合、数据分析创新及临床拓展的未来方向,展示了这些技术在揭示大脑功能机制中的关键作用。

Apple的专栏 119

使用 Python 爬虫抓取 IMDb 电影信息 - 评分、评论与基本信息抓取教程

本文介绍了如何使用 Python 爬虫技术抓取 IMDb 电影评分、评论和基本信息。我们分别展示了通过IMDb API和两种方法抓取数据,并进行了数据存储、分析与可视化。在未来,我们还可以基于这些数据开发电影推荐系统、情感分析工具等,进一步丰富电影数据的应用场景。通过这些实践,您不仅学会了如何抓取和存储数据,还可以通过这些基础来构建自己的数据分析应用,获取更丰富的电影数据。

2201_76125261的博客 601

Android---Window、WindowManager和WMS体系

前言 本篇文章会从源码层面上分析Activity从创建直到在页面上显示的过程。 首先分析一下在这个过程中会遇到的一些接口和类 了解它们的源码以及功能之后再将它们串起来就能够了解整体的流程了 概述 类和接口 1. Window体系 Window体系说白了就是要在页面是显示的View,这个体系中包含多个类来共同完成view的显示其中包括 Activity、Window、PhoneWindow、De...

xiaoqiang_0719的博客 1110

YOLOv8改进:基于EfficientNetV2均衡缩放网络的特征提取层优化【YOLOv8】

YOLO(You Only Look Once)系列模型以其高效的实时目标检测能力而闻名。YOLOv8作为该系列的最新版本,通过引入改进的网络结构和算法优化,进一步提升了目标检测的性能。然而,YOLOv8在特征提取阶段的网络结构仍有改进的空间。EfficientNetV2是一种基于均衡缩放的卷积神经网络,它通过优化网络的宽度、深度和分辨率来实现高效的特征提取。与之前的EfficientNet版本相比,EfficientNetV2在速度和精度上都有显著提升,尤其在处理复杂目标检测任务时表现尤为突出。

博客 1582

重学安卓:Activity 的快乐你不懂!

前言 本文本来是自己复盘 Android 知识梳理用的,没想到在一次部门内部的知识测评中发现,同事们对这些基础知识的掌握参差不齐,甚至可以说是模棱两可。 是网上关于 Activity 的教程太少了吗?不是的,恰恰相反,网上的信息多如牛毛,却没有一篇愿意费哪怕一丝丝的笔墨 来介绍 Activity 的起源、它的职责边界、它的存在到底是为了解决什么问题、我们学习它,到底学到什么程度才算掌握。 正因为对这些最基本而必要的概念模棱两可,使得教程再多、再优秀,也没多少人能消化、能记住。于是我抱着试试看的心态,在经过

xiangxuexi722的博客 252

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

user interface, view 和activity究竟是啥?

 User Interface 这个在安卓中随处可见,随处可及的词语。Uer “用户”的意思,interface“接口,界面”的意思。整合起来理解“用户接口”“用户界面”。 接口Interface,在程序语言中,有着其特殊的含义,场景不同,含义也不一样。在面向对象的设计语言中,接口是对抽象类的抽象,抽象类是对具体类的抽象,具体类是对具有共同属性和方法的对象集合抽象,而具体的对象

何处笙箫 1091

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

理解安卓的视图体系结构

系统的介绍安卓的View的体系结构,让应用开发者对整体窗口有个更清楚的认知

稀有猿诉 1313

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

深入理解 Android Window系统

最后,让我们简要介绍一下如何创建自定义Window。自定义Window允许您完全控制应用程序的UI,以实现特定的界面效果。

Android23333的博客 2341

Android 深入系统源码探讨 Activity、Window 和 View 的关系与实践

Activity 创建并管理一个 PhoneWindow 对象。6.2、PhoneWindow 是 Window 的具体实现,负责管理窗口的视图和装饰。6.3、PhoneWindow 通过 DecorView 容纳内容视图。6.4、Activity 的布局文件通过 setContentView 方法设置到 PhoneWindow,并最终成为 DecorView 的子视图。6.5、ViewRootImpl 连接窗口管理器(WindowManager)和视图层次结构,负责窗口的绘制和输入事件处理。

结合项目案例,记录点点滴滴,自己回顾,分享他人o__o 1万+

Android应用性能优化系列视图篇——优化之路从Window开始

众所周知,Activity是Android应用程序的载体,允许用户在其上创建一个用户界面即视图,而这个视图又是通过Window来管理,所以Window在用户界面即视图中扮演着至关重要的角色。所以,如果要做好视图性能优化,理解Window的本质则是第一步!

MegatronKings的博客 2213

Android | 理解Window 和 WindowManager

前言 Window 是一个窗口的概念,是所有视图的载体,不管是 Activity,Dialog,还是 Toast,他们的视图都是附加在 Window 上面的。例如在桌面显示一个悬浮窗,就需要用到 Window 来实现。WindowManager 是访问 Window 的入口。 Window 是一个抽象类,他的实现类是 PhoneWidow,Activity 中的 DecorView ,Dialog 中的 View 都是在 PhoneWindow 中创建的。因此 Window 实际是 View 的直接管理者,

345丶 4397

Android Window 理解

Window概念 Window即窗口,是一个抽象类,它的唯一实现类是PhoneWindow。Android中的所有视图都是通过Window来呈现的。Window由WindowManagerService进行管理,定义了独立的绘制区域,不予其他Window相互影响。 Window 的三种类型 应用 Window 应用Window需要对应一个Activity 子 Window 子Windo...

lbcwnu的博客 2177

Android 理解Window和WindowManager

Android 理解Window和WindowManager Window表示的是一个窗口的概念,它是一个抽象类,具体实现是PhoneWindow。 创建一个Window只需要通过WindowManager即可完成,WindowManager是外界访问Window的入口。Window的具体实现是在WindowManagerService中,WindowManager与WindowManagerSe...

提辖鲁的博客 694

正确地理解Window窗口概念

Android中Window窗口的准确定义应该是:通过图像的形式响应用于操作的界面。

u010307119的博客 8655

Android Window学习记录(一)理解window和windowmanager

Android Window学习记录(一)理解window和windowmanager一、Window什么是Window小结为什么需要Window小结Window的相关属性window的type属性Window的flags参数window的solfInputMode属性如何给window属性赋值小结Window和WindowManager的关系二、WindowManagerWindow的添加过程Window的删除过程Window的更新过程参考资料 一、Window 什么是Window 在Android框架层

nous_x的博客 3147

Android之理解Window相关类

1 引言 Window及其相关类在Android中是很重要的一部分,平常开发中直接接触Window的情况很少,但是理解Window体系对认识Android结构有很大的帮助。 本文先从Window的基本使用开始,介绍Window的添加、更新和删除操作,然后对这些操作深入分析,并对Window及其相关类做一下整体结构的梳理。 Window是一个庞大的体系,会涉及到其它知识体系,对于这部分内容,本文只是...

MEzzsy的博客 530

Android理解 Window 与 WindowManager

这个东西比较复杂,笔者能力有限,只能把自己理解说一下,如果有不对的地方,望指正。 一 、 Window 介绍 在我们日常开发中,Window 看似接触的不错,实际上,Android 中所有的视图都是通过 Window 来呈现的,不管是 Activity,Dialog、Taost 还是 PupopWindow ,它们的视图其实都是附加在 Window 上的。 Window 是一个抽象类,它的具体类是 PhoneWindow,它的具体实现类位于 WindowManagerService中; 每个 window

夏至的稻穗的博客 870
上一篇: Android架构组件—ViewModel原理学习
下一篇: 深入RecyclerView学习—缓存机制
Coding-ls
博客等级 码龄11年 41粉丝 61原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值