通过前几篇的文章(查看系列文章:http://www.cnblogs.com/jerehedu/p/4607599.html#gui ),我们清楚了Activity实际上是将视图的创建和显示交给了Window对象进行了处理并分析了视图的测量、布局及绘制过程。本篇文章将继续详细分析Window及WindowManger的作用。

  首先,我们将通过下图弄清楚他们之间的关系。

  通过前几篇的文章,我们清楚了Activity实际上是将视图的创建和显示交给了Window对象进行了处理并分析了视图的测量、布局及绘制过程。本篇文章将继续详细分析Window及WindowManger的作用。

  首先,我们将通过下图弄清楚他们之间的关系。

   /** Flag for the "options panel" feature.  This is enabled by default. */
public static final int FEATURE_OPTIONS_PANEL = 0;
/** Flag for the "no title" feature, turning off the title at the top
* of the screen. */
public static final int FEATURE_NO_TITLE = 1; //无标题栏
/** Flag for the progress indicator feature */
public static final int FEATURE_PROGRESS = 2; //在标题栏上添加加载进度条
/** Flag for having an icon on the left side of the title bar */
public static final int FEATURE_LEFT_ICON = 3;
/** Flag for having an icon on the right side of the title bar */
public static final int FEATURE_RIGHT_ICON = 4;
/** Flag for indeterminate progress */
public static final int FEATURE_INDETERMINATE_PROGRESS = 5;
/** Flag for the context menu. This is enabled by default. */
public static final int FEATURE_CONTEXT_MENU = 6;
/** Flag for custom title. You cannot combine this feature with other title features. */
public static final int FEATURE_CUSTOM_TITLE = 7;
public static final int FEATURE_ACTION_BAR = 8;
public static final int FEATURE_ACTION_BAR_OVERLAY = 9;
public static final int FEATURE_ACTION_MODE_OVERLAY = 10;
public static final int FEATURE_MAX = FEATURE_ACTION_MODE_OVERLAY;
/** Flag for setting the progress bar's visibility to VISIBLE */
public static final int PROGRESS_VISIBILITY_ON = -1;
/** Flag for setting the progress bar's visibility to GONE */
public static final int PROGRESS_VISIBILITY_OFF = -2;
/** Flag for setting the progress bar's indeterminate mode on */
public static final int PROGRESS_INDETERMINATE_ON = -3;
/** Flag for setting the progress bar's indeterminate mode off */
public static final int PROGRESS_INDETERMINATE_OFF = -4;
/** Starting value for the (primary) progress */
public static final int PROGRESS_START = 0;
/** Ending value for the (primary) progress */
public static final int PROGRESS_END = 10000;
/** Lowest possible value for the secondary progress */
public static final int PROGRESS_SECONDARY_START = 20000;
/** Highest possible value for the secondary progress */
public static final int PROGRESS_SECONDARY_END = 30000;

  那么如何应用这些窗口特征呢?在Activity中,我们可以调用方法requestWindowFeature,实际此方法是调用了Window中的requestFeature的方法,方法原型如下:

    public boolean requestFeature(int featureId) {
final int flag = 1<<featureId;
mFeatures |= flag;
mLocalFeatures |= mContainer != null ? (flag&~mContainer.mFeatures) : flag;
return (mFeatures&flag) != 0;
}

  注意此方法必须在setContentView方法之前调用才有效,一旦应用了这些窗口特征后续不可更改。

  在window中定义了一个CallBack接口,此接口中一定了一系列的时间回调方法,用于处理UI的各种事件,如按键事件、触摸事件、轨迹球、Accessibility事件、菜单事件等等。比如Activity就实现了此接口。关于事件这块的内容,我们后面专门做分析研究。

  在window中还定义了WindowManager,从字面上可以理解为窗口管理器,实际上它并不是真正的窗口管理器,WindowManager Service才是Android中真正意义上的窗口管理器。实际上Window内的WindowManager只是用于管理Window内部的视图,通过方法setWindowManager,可以看到Window中是如何创建WindowManager的,具体源码如下:

  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的createLoaclWindowManager方法创建了一个WindowManager对象。

  从上图中,我们看出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);
}

  很好理解主要用于window中view的添加、更新和删除。

  WindowManager接口内容也比较简单,除了继承自ViewManager中的方法外,还定义了3个内部类和两个方法,具体API如下。

  在这里我们要重点关注一下LayoutParams这个内部类,此类定义了许多与窗口相关的属性,比如位置、窗口类型(主要有三类:Application Windows、Sub-windows、System windows)、行为选项标志、窗口透明度等等,在此不再贴源码了,有兴趣的可以自行查看。

  从window中的方法setWindowManager中可以看出创建的WindowManager的对象实际上是WindowManagerImpl,此类是WindowManager的实现类,源码如下:

public final class WindowManagerImpl implements WindowManager {
private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
private final Display mDisplay;
private final Window mParentWindow;
public WindowManagerImpl(Display display) {
this(display, null);
}
private WindowManagerImpl(Display display, Window parentWindow) {
mDisplay = display;
mParentWindow = parentWindow;
}
public WindowManagerImpl createLocalWindowManager(Window parentWindow) {
return new WindowManagerImpl(mDisplay, parentWindow);
}
public WindowManagerImpl createPresentationWindowManager(Display display) {
return new WindowManagerImpl(display, mParentWindow);
}
@Override
public void addView(View view, ViewGroup.LayoutParams params) {
mGlobal.addView(view, params, mDisplay, mParentWindow);
}
@Override
public void updateViewLayout(View view, ViewGroup.LayoutParams params) {
mGlobal.updateViewLayout(view, params);
} @Override
public void removeView(View view) {
mGlobal.removeView(view, false);
} @Override
public void removeViewImmediate(View view) {
mGlobal.removeView(view, true);
} @Override
public Display getDefaultDisplay() {
return mDisplay;
}
}

  该实现类比较简单,主要持有Window类型的mParentWindow对象,并提供一系列的方法用于构建WindowManagerImpl对象,其他方法的实现主要调用WindowManagerGlobal对象中的响应方法。

  在window的setWindowManager方法主要调用了WindowManagerImpl的createLocalWindowManager创建了WindowManager对象,这样就将Window和WindowManager关联起来了,也就意味在调用WindowManager的addView、updateViewLayout、removeView时实际上操作的是Window内部的View,这一点可以通过查看WindowManagerGlobal相关方法的源码可以看出。

  疑问咨询或技术交流,请加入官方QQ群: (452379712)

作者:杰瑞教育
出处:http://www.cnblogs.com/jerehedu/ 
本文版权归烟台杰瑞教育科技有限公司和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
 

Android GUI之Window、WindowManager的更多相关文章

  1. 图解Android - Android GUI 系统 (2) - 窗口管理 (View, Canvas, Window Manager)

    Android 的窗口管理系统 (View, Canvas, WindowManager) 在图解Android - Zygote 和 System Server 启动分析一 文里,我们已经知道And ...

  2. android 中View, Window, Activity, WindowManager,ViewRoot几者之间的关系

    (1)View:最基本的UI组件,表示屏幕上的一个矩形区域. (2)Window: 表示一个窗口,不一定有屏幕那么大,可以很大也可以很小:                         它包含一个V ...

  3. 图解Android - System Service 概论 和 Android GUI 系统

    通过 图解Android - Binder 和 Service 一文中,我们已经分析了Binder 和 Service的工作原理.接下来,我们来简要分析Android 系统里面都有哪些重要的Servi ...

  4. 图解Android - Android GUI 系统 (1) - 概论

    Android的GUI系统是Android最重要也最复杂的系统之一.它包括以下部分: 窗口和图形系统 - Window and View Manager System. 显示合成系统 - Surfac ...

  5. 图解Android - Android GUI 系统 (5) - Android的Event Input System

    Android的用户输入处理 Android的用户输入系统获取用户按键(或模拟按键)输入,分发给特定的模块(Framework或应用程序)进行处理,它涉及到以下一些模块: Input Reader: ...

  6. [虾扯蛋] android界面框架-Window

    从纯sdk及framwork的角度看,android中界面框架相关的类型有:Window,WindowManager,View等.下面就以这几个类为出发点来概览下安卓开发的"界面架构&quo ...

  7. android Gui系统之SurfaceFlinger(1)---SurfaceFlinger概论

    GUI 是任何系统都很重要的一块. android GUI大体分为4大块. 1)SurfaceFlinger 2)WMS 3)View机制 4)InputMethod 这块内容非常之多,但是理解后,可 ...

  8. android Gui系统之SurfaceFlinger(1)---SurfaceFlinger概论【转】

    转自:https://www.cnblogs.com/deman/p/5584198.html 阅读目录 1.OpenGL & OpenGL ES 2.Android的硬件接口HAL 3.An ...

  9. Android GUI系统

    图解Android - Android GUI 系统 (1) - 概论 图解Android - Android GUI 系统 (2) - 窗口管理系统 图解Android - Android GUI ...

随机推荐

  1. myeclipse 插件下载方式

    myeclipse10,大家都知道,MyEclipse 中有一个烦人的 Software and Workspace center,这东西,加载特别慢,我用10版本基本是没有可能看到这个界面.更别说在 ...

  2. 4040 EZ系列之奖金

    4040 EZ系列之奖金 时间限制: 1 s 空间限制: 64000 KB 题目等级 : 钻石 Diamond   题目描述 Description 由于无敌的WRN在2015年世界英俊帅气男总决选中 ...

  3. voith项目配置服务程序

    项目需求: 1.程序可以最小化到任务栏 2.tpms标签和限速标签同时只能选择一个,并且要通过button确定修改 3.在程序中需要显示SequenceScanner1.0服务的运行状态 4.能够打开 ...

  4. mutiplemap 总结

    之前只是在C++ Primer里面看过关联容器,可能因为没有实际用过,只是看看,所以导致用的时候并不熟悉: 在这之前,map和set的特性应该要了解,map是关联数组,也就是由键值对组成的,而set只 ...

  5. 【JavaScript代码实现一】数组去重

    function arrayNoDupulate(array) { var hash = {}; var result = []; for(var i=0;i<array.length;i++) ...

  6. Antd前端开发采坑记录

    背景 基于页面友好,界面整洁美观:基于Antd框架开发虾能平台 选型 基于Antd-admin工程架构,进行开发:基于Antd+React+Umj 采坑记录 按照Html方式天机onClick方法,每 ...

  7. react父子组件数据传递

    子传父 1.首先父组件设定一个自定义函数 getChildDatas = (values) => { //...业务代码 } 2.将该函数暴露在子组件的引用上 <Child getChil ...

  8. cocos2dx -- 学习笔记

    在导入 cocos-ext.h 时项目会报错. 需要在 Additional Include Directories 中增加 $(EngineRoot) 并置顶(试验,不置顶也可以) 如果找不到当前目 ...

  9. HDU 4707 Pet (水题)

    Pet Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

  10. Windows Performance Toolkit

    http://bigasp.com/archives/606 https://randomascii.wordpress.com/category/xperf/ ADK 8.0  (C:\Progra ...