Android之WindowManager介绍

news2025/1/15 16:57:19

WindowManager

android中真正展示给用户的是window和view.

activity在android中所其的作用主要是处理一些逻辑问题,比如生命周期的管理、建立窗口等。

在android中,窗口的管理还是比较重要的一块,因为他直接负责把内容展示给用户,并和用户进行交互。响应用户的输入等。

WindowManager继承自ViewManager,里面涉及到窗口管理的三个重要方法,分别是:
* addView();
* updateViewLayout();
* removeView();

Window

android的窗口分为三种:
1、应用程序窗口 (Application Window): 包括所有应用程序自己创建的窗口,以及在应用起来之前系统负责显示的窗口。
2、子窗口(Sub Window):比如应用自定义的对话框,或者输入法窗口,子窗口必须依附于某个应用窗口(设置相同的token)。
3、系统窗口(System Window): 系统设计的,不依附于任何应用的窗口,比如说,状态栏(Status Bar), 导航栏(Navigation Bar), 壁纸(Wallpaper), 来电显示窗口(Phone),锁屏窗口(KeyGuard), 信息提示窗口(Toast), 音量调整窗口,鼠标光标等等。


 Window.java是个虚类:

public abstract class Window {}

他的具体实现是 PhoneWindow.java 。

PhoneWindow对象被创建是在Activity中:

    final void attach(Context context, ActivityThread aThread,
            Instrumentation instr, IBinder token, int ident,
            Application application, Intent intent, ActivityInfo info,
            CharSequence title, Activity parent, String id,
            NonConfigurationInstances lastNonConfigurationInstances,
            Configuration config, String referrer, IVoiceInteractor voiceInteractor,
            Window window, ActivityConfigCallback activityConfigCallback) {
        attachBaseContext(context);
        ……

        mWindow = new PhoneWindow(this, window, activityConfigCallback);
        mWindow.setWindowControllerCallback(this);
        mWindow.setCallback(this);
        mWindow.setOnWindowDismissedCallback(this);
        mWindow.getLayoutInflater().setPrivateFactory(this);
             ……

        mWindow.setWindowManager(
                (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
                mToken, mComponent.flattenToString(),
                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
        ……
    }

 代码中会调用PhoneWindow的setWindowManager函数(实现在Windows类中):

    public void setWindowManager(WindowManager wm, IBinder appToken, String appName) {
        setWindowManager(wm, appToken, appName, false);
    }

    public void setWindowManager(WindowManager wm, IBinder appToken, String appName,
            boolean hardwareAccelerated) {
        mAppToken = appToken;
        mAppName = appName;
        mHardwareAccelerated = hardwareAccelerated
                || SystemProperties.getBoolean(PROPERTY_HARDWARE_UI, false);
        if (wm == null) {
            wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
        }
        mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);
    }

这里看到会执行WindowManagerImpl.java的createLocalWindowManager函数:

    public WindowManagerImpl createLocalWindowManager(Window parentWindow) {
        return new WindowManagerImpl(mContext, parentWindow);
    }

所以最后mWindowManager 保存了一个local的WindowManager.

之前传进来的WindowManagerImpl实例又去创建了一个具有ParentWindow的WindowManagerImpl实例,根据他的参数可以看出,这里的Window是作为WindowManagerImpl的parentWindow的,也就是他们俩的关系从表面看上去好像是父级和子级的层级关系。

WindowManager的功能介绍

Window是一个抽象的概念,每一个Window都对应着一个View和一个ViewRootImpl,Window和View通过ViewRootImpl来建立联系,说明View才是Window存在的实体,在实际使用中无法直接访问Window,对Window的访问必须通过WindowManager。

Window的添加过程需要通过WindowManager的addView来实现,WindowManager是一个接口,它的真正实现是WindowManagerImpl类。

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

mGlobal是WindowManagerGlobal:

private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();

WindowManager操作Window,不过具体的实现细节还是WindowManagerGlobal这个类来做的,这个类是一个单例模式。

继续看下WindowManagerGlobal.java的addView函数:

    public void addView(View view, ViewGroup.LayoutParams params,
            Display display, Window parentWindow) {
        ……

        final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
        if (parentWindow != null) {
            // 界面布局的限制
            parentWindow.adjustLayoutParamsForSubWindow(wparams);
        } else {
            final Context context = view.getContext();
            if (context != null
                    && (context.getApplicationInfo().flags
                            & ApplicationInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
                wparams.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
            }
        }

        ViewRootImpl root;
        View panelParentView = null;

        synchronized (mLock) {
             ……
            // 构建界面控制
            root = new ViewRootImpl(view.getContext(), display);

            view.setLayoutParams(wparams);

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

            try {
                //将View显示到手机窗口
                root.setView(view, wparams, panelParentView);
            } catch (RuntimeException e) {
                if (index >= 0) {
                    removeViewLocked(index, true);
                }
                throw e;
            }
        }
    }

其中创建了ViewRootImpl 。

ViewRootImpl 是一个视图层次结构的顶部,ViewRootImpl 实现了 View 与 WindowManager 之间所需要的协议,作为 WindowManagerGlobal 中大部分的内部实现。

在 WindowManagerGlobal 中实现方法中,都可以见到 ViewRootImpl,也就说 WindowManagerGlobal 方法最后还是调用到了 ViewRootImpl。

比如addView,removeView,update 的调用顺序:WindowManagerImpl -> WindowManagerGlobal -> ViewRootImpl.

而且WindowManager.java 是继承的ViewManager .

public interface WindowManager extends ViewManager {}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/501506.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

11.streamFile

1.Stream流 1.1体验Stream流【理解】 案例需求 按照下面的要求完成集合的创建和遍历 创建一个集合,存储多个字符串元素把集合中所有以"张"开头的元素存储到一个新的集合把"张"开头的集合中的长度为3的元素存储到一个新的集合遍历上一步得到的集…

05-微服务部署2023系列-centos+docker部署redis(单机版)

1、创建数据挂载目录 mkdir /root/docker/redisCluster/redis1/data -p 2、部署并启动命令 docker run -itd --privileged=true --name redisMaster -p 19000:6379 -v /root/docker/redisCluster/redis1/data:/data redis --appendonly yes --requirepass "myRedisPass123…

美颜sdk的开发流程及其在不同平台上的适用性比较

当下,在开发美颜功能时,美颜sdk成为了不可或缺的工具。近期,很多开发者向小编提问开发美颜的一些专业技术问题。本篇文章,小编将为大家统一解答一下近期的热门问题。 一、开发流程 1、确定美颜算法 美颜算法是美颜sdk的核心&a…

【Linux下】进程间通信

文章目录 进程间通信进程间通信的目的进程间通信的分类进程间通信的本质 管道初识管道匿名管道创建匿名管道理解协同机制和原子性写入 命名管道命名管道创建的俩种方式使用命名管道实现俩个不同进程之间通信 **管道实现进程间通信的本质**匿名管道vs命名管道 system Vsystem V共…

【Linux】进程概述和进程状态转换(查看进程、实时显示进程动态、杀死进程等)

目录 进程概述进程状态转换进程的状态进程相关命令 橙色 进程概述 进程是正在运行的程序的实例,是基本的分配单元也是基本的执行单元。 可以用一个程序来创建多个进程,进程是由内核定义的抽象实体,并为该实体分配用以执行程序的各项系统资源…

【Jmeter快速入门】

Jmeter快速入门 Jmeter快速入门1.安装Jmeter1.1.下载1.2.解压1.3.运行 2.快速入门2.1.设置中文语言2.2.基本用法 Jmeter快速入门 1.安装Jmeter Jmeter依赖于JDK,所以必须确保当前计算机上已经安装了JDK,并且配置了环境变量。 1.1.下载 可以Apache Jm…

git在vs可视化界面下变基操作

vs版本:vs2022 天天都在使用git,听说过变基这个名词,但是并没有实操过变基,正好今天有个同事说起一件事情:提交代码的时候有太多的自动合并,如果需要回退版本,操作起来很困难,理想状…

如何在项目中实现登录时的验证码校验功能?

如何在项目中实现登录时的验证码校验功能? 第一步:创建项目,添加依赖第二步:验证码配置(CaptchaConfig类)第三步:创建CaptchaController第四步:测试注意问题 这里介绍一款老牌的验证…

使用@Resource注解和@Inject注解

1.Resource和Inject概述 1.1.Resource注解 Resource注解是Java规范里面的,也可以说它是JSR250规范里面定义的一个注解。该注解默认按照名称进行装配,名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时&…

KCC南京成立会议如期举办

1915年9月15日,陈独秀等人在上海创立了《新青年》杂志,掀起了中华新文化思潮。接着,在1919年5月4日,陈独秀、李大钊等人发起了五四运动,唤醒了沉睡多年的东方巨狮。从此,五四青年节便成为了青年人的节日。 …

上市后首份财报,紫燕食品去年净利下降超3成

近日,上海紫燕食品股份有限公司(下称“紫燕食品”,603517.SH)交出了上市后的首份年报。 去年9月26日,紫燕食品在上交所主板上市,成为继绝味食品(603517.SH)、周黑鸭(01458.HK&#…

Jetpack Compose 中的Deep Linking — Android

Jetpack Compose 中的Deep Linking — Android 在本文中,我们将学习如何在 Jetpack Compose 中轻松实现深度链接。 什么是深度链接? 深层链接允许用户直接从外部来源(例如网站或其他应用程序)导航到应用程序内的特定内容。 添…

联想笔记本系统更新中断后变成蓝屏怎么U盘重装系统?

联想笔记本系统更新中断后变成蓝屏怎么U盘重装系统?有用户使用的联想笔记本电脑在系统更新的过程中,因为自己进行了一些操作,导致系统更新中断了,重启系统之后变成了蓝屏的情况。那么这个时候怎么去通过U盘重装系统来恢复电脑使用…

2d游戏人物动作实现(C语言)

没有接触制作小游戏前,感觉做游戏很不可思议,游戏里的人物是怎么移动的,怎么攻击,释放技能。。。。。。现在逐渐了解到之后,发现2d游戏人物的动作更多是图片的拼接,动作是否精细,由这个动作的帧…

第四十二章 Unity 下拉框 (Dropdown) UI

本章节我们介绍下拉框 (Dropdown),我们点击菜单栏“GameObject”->“UI”->“Dropdown”,然后调整它的位置,效果如下 其实它的本质就是一个下拉列表,然后选择列表中的一个选项而已。大家在很多网页中应该可以看到类似的UI元…

asp.net+sqlserver学生学籍管理系统

1.系统登录模块:为了保证系统的安全性和保密性,便于用户的管理,对用户设置权限。 界面上需要输入用户名、密码、验证码以及用户类型。 用户类型:普通用户和管理员用户。 2.用户信息管理模块&…

Solr(4):Solr索引库说明及创建

1 索引库概述 索引库类似于mysql的数据库,所以如果要使用Solr必须创建一个索引库才能使用 2 使用solr管理页面去创建【不推荐】 2.1 打开solr的管理页面 2.2 点击add Core name:自定义名字 建议和instanceDir目录保持一样instanceDir:实例名…

两大巨头强强联手,为亿万旅行者提供完美旅程

‍数据智能产业创新服务媒体 ——聚焦数智 改变商业 这个“五一”你买到票了么? 今年五一火爆程度可谓“盛况空前”,4月28号(放假前一天)上海单日通往全国所有车站的车票售罄,这是115年以来首次出现这种情况。不仅是上…

javaScript---设计模式-提高复用性

目录 1、提高复用性的设计模式 2、基本结构与应用示例 2.1 享元模式 2.2 桥接模式 2.3 模板方法模式 2.4 JS的组合与继承 提高复用性的目的:①遵循DRY(Dont Repeat Yourself)原则;②减少代码量,节省开销 什么是好的复用…

Android安装apk出现 “安装包无效”或“安装包不兼容”的解决方案

Android 安装apk出现“安装包无效”或“安装包不兼容”解决方案 1. 问题出现2. 配置 build.gradle3. 生成Signed APK 1. 问题出现 使用Android Studio安装apk到手机一切正常,但是分享出去出现安装apk出现“安装包无效”或“安装包不兼容”问题 这种情况需要我们设…