Android View, Window,Activity概念区分(2)

本文详细解析了Android系统中的视窗机制,包括View、Window、Activity之间的关系,以及WindowManager的作用。介绍了如何创建和管理窗口,揭示了Activity、Window、View和ViewRoot之间的交互过程。

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

(1)View:最基本的UI组件,表示屏幕上的一个矩形区域。

(2)Window: 表示一个窗口,不一定有屏幕那么大,可以很大也可以很小;
它包含一个View tree和窗口的layout 参数。
View tree的root View可以通过getDecorView得到。还可以设置Window的Content View。

(3)Activity:Activity包含一个Window,该Window在Activity的attach方法中通过调用
PolicyManager.makeNewWindo创建

(4)WindowManager:一个interface,继承自ViewManager。 有一个implementation

(5)class:android.view.WindowManagerImpl

其实WindowManager并不是整个系统的窗口管理器,而是所在应用进程的窗口管理器。系统全局的窗口管理器运行在SystemServer进程中,是一个Service。

ViewRoot通过IWindowSession接口与全局窗口管理器进行交互。 将一个View add到WindowManager时,WindowManagerImpl创建一个ViewRoot来管理该窗口的根View。并通过ViewRoot.setView方法把该View传给ViewRoot。

ViewRoot用于管理窗口的根View,并和global window manger进行交互。ViewRoot中有一个nested class: W,W是一个Binder子类,用于接收global window manager的各种消息, 如按键消息, 触摸消息等。 ViewRoot有一个W类型的成员mWindow,ViewRoot在Constructor中创建一个W的instance并赋值给mWindow。 ViewRoot是Handler的子类, W会通过Looper把消息传递给ViewRoot。 ViewRoot在setView方法中把mWindow传给sWindowSession。



ActivityThread.java中调用wm.addView(decor, l);把它加入到window manager
proxy的mViews中,同时为这个decor view创建一个ViewRoot,ViewRoot负责协调decor view与window
manager直接绘图、事件处理。

ViewRoot中有IWindowSession和IWindow用来和window manger打交道和接收window
manager传过来的消息,消息传过来后ViewRoot分发给decor view,再由decor view进行分发



总之,每个窗口对应着一个Window对象,一个根View和一个ViewRoot对象。要想创建一个窗口,可以调用
WindowManager的addView方法,作为参数的view将作为在该窗口上显示的根view

一般来讲,Activity就是一 个可视的人机交互界面。
每一个Activity都有一个默认的Window,一 般来讲,这个Window都是全屏的,当然也有例外,比如Dialog的Window就是非全屏的。Activity也可以利用默认Window以外的其 它的Window,比如弹出一个Dialog对话框。6 i8 J' I' b+ v. F% r
Window里可见的内容,就是一层一层的View。Window里的View是通过setContentView这个接口set进去的,这个ContentView就是Window里处于最根部的View。
 
 
对于屏幕显示而 言,整个是Activity 其实确切的说是window,为什么这样说呢?

在Activityattach 函数里.有这样一句 mWindow = PolicyManager.makeNewWindow(this);

这句是把Activiyt window关联起来了.真正关联的是PhoneWindow.

这个window里显示的东西是view(activity是逻辑上的东 西,增加了生命周期管理等. 里面具体的东西也是view。而且启动activity的实现也是往window里加view),往window里加view,是通过调用WindowManager(WindowManagerImpl).addView()来实现的。

为什么可以这样说呢?

看public void setContentView(int layoutResID) {
getWindow().setContentView(layoutResID);
}


在addView里,会为每个view创建一个viewRoot(这是逻辑上的东西,用来负责view的事件处理和逻辑处理,并和WindowsManagerService建立联系),而在WindowManagerImpl里,会维护viewRoot的数组。

最 终会调用ViewRoot.setView(),在setView里会显示该view等。在setView的实现里,会调用Session.add()来addWindow,通过这个方法,会将ViewRoot和WindowManagerService联系起来(比如说分发事件等),并且这个方法里会调 用PhoneWindowManager.prepareAddWindowLw()。

这只是模糊概念,还有细节需要推敲,我会继续努 力.如果你感觉是这么会事,你得给我顶了,我也不容易的.都很辛苦啊.

转载于:https://www.cnblogs.com/qishuai/p/4496661.html

<think>嗯,用户现在的问题聚焦在Android开发中的一个具体属性isTranslucent上,这属于系统UI控制的范畴。从技术深度来看,用户应该是有实际开发需求的工程师,而非初学者——因为初学者通常会问更基础的“如何实现半透明效果”这类问题。注意到用户特意强调引用内容仅供参考,说明ta更关注实际解决方案而非理论框架。结合历史记录,上次讨论的是Android系统级UI控制,这次延续了窗口管理的技术路线,但更具体到透明效果实现。让我拆解isTranslucent的关键技术点:首先它是Activity级别的属性,与主题系统强相关;其次需要区分系统窗口应用窗口的透明效果;最后还要考虑版本兼容问题(尤其是Android4.4前后变化)。用户可能的真实需求场景包括:实现毛玻璃通知栏、创建沉浸式启动页、或者制作特殊转场动画。可以准备几个典型代码示例,但要控制技术细节的颗粒度——毕竟手机屏幕展示空间有限。需要特别注意技术边界的说明:比如DecorViewSystemUiController的关系、FLAG_TRANSLUCENT与View.SYSTEM_UI_FLAG的区别。系统窗口渲染流程可能超出用户需求范围,但涉及沉浸式实现时又必须提及。发现潜在风险点:半透明状态栏在全面屏手机上的安全区适配问题,这个虽未在query中提及,但属于实际开发必坑项,应当主动提示。准备在“实现细节”部分引入displaycutout的适配方案。对于系统级机制,考虑用ViewServer架构图来说明但最终否决了——毕竟用户要的是实用方案而非框架原理。改用更直白的窗口层级示意图会更有效,但需要控制字数。</think> 在 Android 开发中,`windowIsTranslucent` 是控制窗口(Activity/Fragment)透明度的关键属性,属于**系统级 UI 渲染机制**的实现。以下是具体解析: --- ### **一、核心实现方式** 在 `styles.xml` 中定义透明主题(推荐 API 21+): ```xml <style name="TranslucentTheme" parent="Theme.AppCompat.Light.NoActionBar"> <item name="android:windowBackground">@android:color/transparent</item> <!-- 关键属性 --> <item name="android:windowIsTranslucent">true</item> <item name="android:windowNoTitle">true</item> </style> ``` 在 `AndroidManifest.xml` 应用主题: ```xml <activity android:name=".TranslucentActivity" android:theme="@style/TranslucentTheme"/> ``` --- ### **二、核心作用机制** 1. **视图层级结构** 启用后,系统会跳过默认窗口背景的绘制流程,直接合成 `DecorView` 内容。此时 Activity 布局的根视图直接与系统窗口叠加渲染[^1]。 2. **生命周期影响** ```mermaid graph LR A[Activity.onCreate] --> B[系统跳过背景绘制] B --> C[布局直接绑定到系统窗口] C --> D[内容直接显示] ``` 此模式下 `onResume()` 执行前界面即部分可见,可能影响冷启动性能。 3. **窗口标志位 (WindowManager.LayoutParams)** 在代码中动态设置等价于: ```kotlin window.setFlags( WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS ) ``` --- ### **三、典型用例与限制** | **场景** | **实现方式** | **注意事项** | |---------------------|--------------------------|----------------------------------| | 半透明启动屏 | 主题中设置 `windowIsTranslucent` | 需处理初始化阻塞导致界面卡顿 | | 沉浸式状态栏 | 配合 `fitsSystemWindows="true"` | Android 4.4+ 需额外处理系统栏颜色 | | 窗口叠加动画 | 动态修改 Window 的 alpha 值 | 避免影响下层 Activity 的生命周期 | --- ### **四、兼容性方案(低版本适配)** 针对 API < 21 的设备: ```java if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); } else { getWindow().setStatusBarColor(Color.TRANSPARENT); } ``` --- ### **五、性能优化建议** 1. **避免全局使用** 仅在需要透明效果的 Activity 启用,减少过度绘制。 2. **启动优化策略** ```kotlin // 在 setContentView 前执行 window.setBackgroundDrawable(null) ``` 3. **替代方案考虑** 使用 `android:windowBackground` 设置半透明色值,代替完全透明窗口: ```xml <item name="android:windowBackground">#80000000</item> <!-- 50% 黑色透明 --> ``` --- **附:系统渲染流程关键点** 透明窗口会绕过 SurfaceFlinger 的默认合成路径,直接通过 OpenGL ES 的混合模式(`GL_BLEND`)计算像素叠加,这一过程由 **WindowManagerService** 协调完成[^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值