Android-Framework学习笔记(十一)WindowManager体系

本文详细解释了Android中WindowFlag的设置方法,包括WindowManager.LayoutParams的使用,以及如何处理软键盘模式和窗口添加过程,特别关注了Activity和PhoneWindow的初始化与WindowManager的交互。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

public static final int FLAG_ALLOW_LOCK_WHILE_SCREEN_ON = 0x00000001;
//窗口不能获得输入焦点,设置该标志的同时,FLAG_NOT_TOUCH_MODAL也会被设置
public static final int FLAG_NOT_FOCUSABLE = 0x00000008;
//窗口不接收任何触摸事件
public static final int FLAG_NOT_TOUCHABLE = 0x00000010;
//在该窗口区域外的触摸事件传递给其他的Window,而自己只会处理窗口区域内的触摸事件
public static final int FLAG_NOT_TOUCH_MODAL = 0x00000020;
//只要窗口可见,屏幕就会一直亮着
public static final int FLAG_KEEP_SCREEN_ON = 0x00000080;
//允许窗口超过屏幕之外
public static final int FLAG_LAYOUT_NO_LIMITS = 0x00000200;
//隐藏所有的屏幕装饰窗口,比如在游戏、播放器中的全屏显示
public static final int FLAG_FULLSCREEN = 0x00000400;
//窗口可以在锁屏的窗口之上显示
public static final int FLAG_SHOW_WHEN_LOCKED = 0x00080000;
//当用户的脸贴近屏幕时(比如打电话),不会去响应此事件
public static final int FLAG_IGNORE_CHEEK_PRESSES = 0x00008000;
//窗口显示时将屏幕点亮
public static final int FLAG_TURN_SCREEN_ON = 0x00200000;

设置Window的Flag有三种方法,第一种是通过Window的addFlags方法:

Window mWindow =getWindow();
mWindow.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

第二种通过Window的setFlags方法,其实内部还是会调用setFlags方法:

Window mWindow =getWindow();
mWindow.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);

第三种则是给LayoutParams设置Flag,并通过WindowManager的addView方法进行添加:

WindowManager.LayoutParams mWindowLayoutParams = new WindowManager.LayoutParams();
mWindowLayoutParams.flags = WindowManager.LayoutParams.FLAG_FULLSCREEN;
WindowManager mWindowManager =(WindowManager)getSystemService(Context.WINDOW_SERVICE);
TextView mTextView=new TextView(this);
mWindowManager.addView(mTextView, mWindowLayoutParams);

软键盘相关模式

窗口和窗口的叠加是非常常见的场景,但如果其中的窗口是软键盘窗口,可能就会出现一些问题,比如典型的用户登录界面,默认的情况弹出的软键盘窗口可能会盖住输入框,这样用户体验会非常糟糕。

为了使得软键盘窗口能够按照期望来显示,WindowManager的静态内部类LayoutParams中还定义了软键盘相关模式,这里给出常用的几个:

//没有指定状态,系统会选择一个合适的状态或依赖于主题的设置
public static final int SOFT_INPUT_STATE_UNSPECIFIED = 0;
//不会改变软键盘状态
public static final int SOFT_INPUT_STATE_UNCHANGED = 1;
//当用户进入该窗口时,软键盘默认隐藏
public static final int SOFT_INPUT_STATE_HIDDEN = 2;
//当窗口获取焦点时,软键盘总是被隐藏
public static final int SOFT_INPUT_STATE_ALWAYS_HIDDEN = 3;
//当软键盘弹出时,窗口会调整大小
public static final int SOFT_INPUT_ADJUST_RESIZE = 0x10;
//当软键盘弹出时,窗口不需要调整大小,要确保输入焦点是可见的
public static final int SOFT_INPUT_ADJUST_PAN = 0x20;

从上面给出的SoftInputMode ,可以发现,它们与AndroidManifest中Activity的属性android:windowSoftInputMode是对应的。因此,除了在AndroidMainfest中为Activity设置android:windowSoftInputMode以外还可以在Java代码中为Window设置SoftInputMode:

getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);

Window的添加过程

WindowManager对Window的操作最终都是交由WMS来进行处理。窗口的操作分为两大部分,一部分是WindowManager处理部分,另一部分是WMS处理部分。我们知道Window分为三大类,分别是:Application Window(应用程序窗口)、Sub Windwow(子窗口)和System Window(系统窗口),对于不同类型的窗口添加过程会有所不同,但是对于WMS处理部分,添加的过程基本上是一样的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

无论是哪种窗口,它的添加过程在WMS处理部分中基本是类似的,只不过会在权限和窗口显示次序等方面会有些不同。但是在WindowManager处理部分会有所不同,这里以最典型的应用程序窗口Activity为例。

Activity在启动过程中,会调用ActivityThread的handleLaunchActivity()方法,具体可以参考Framework学习

Android Framework 层是 Android 系统中非常重要的一层,它提供了丰富的 API 和服务,包括 Activity、Service、Content Provider、Broadcast Receiver、PackageManager、Window Manager 等等,它们为应用程序提供了一个丰富的运行环境和开发框架。 Android Framework 层的源码主要包括以下几个部分: 1. Activity Manager:负责管理 Android 应用程序的生命周期、进程和任务栈等。 2. Package Manager:负责管理应用程序的安装、卸载和更新等操作。 3. Content Provider:提供了一种标准的接口,让应用程序之间可以共享数据。 4. Telephony Manager:提供了访问手机通讯功能的接口和服务。 5. Location Manager:提供了访问 GPS 和其他位置服务的接口和服务。 6. Notification Manager:提供了管理通知的接口和服务。 7. View System:提供了 Android 应用程序的 UI 界面的渲染和事件处理等功能。 8. Resource Manager:提供了访问 Android 应用程序的资源文件的接口和服务。 9. Window Manager:提供了窗口管理和界面绘制等功能。 10. Activity Manager Service:提供了 Activity Manager 的服务接口。 11. System Server:提供了 Android 系统的核心服务,包括 PackageManager、ActivityManager、WindowManager 等。 以上是 Android Framework 层源码的主要部分,通过阅读 Android Framework 层源码可以深入了解 Android 系统的实现原理和应用程序的开发框架。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值