• 补充说明Window、PhoneWindow与DecorView

    相关类的介绍
    服务器君一共花费 15.588 ms 进行了 4 次数据库查询,努力地为您提供了这个页面。
    广告很萌的

    在前面 Android用户界面与View/ViewGroup 这一小节中,我们大概理解了View/ViewGroup的概念。但是它们仅仅是界面的一部分,正如下图所示:

    对相关类的作用进行一下简单介绍:

    • Window 类   位于 /frameworks/base/core/java/android/view/Window.java。该类是一个抽象类,提供了绘制窗口的一组通用API。可以将之理解为一个载体,各种View在这个载体上显示。
    • PhoneWindow类  位于/frameworks/policies/base/phone/com/android/internal/policy/impl/PhoneWindow.java。该类继承于Window类,是Window类的具体实现,即我们可以通过该类具体去绘制窗口。并且,该类内部包含了一个DecorView对象,该DectorView对象是所有应用窗口(Activity界面)的根View。 简而言之,PhoneWindow类是把一个FrameLayout类即DecorView对象进行一定的包装,将它作为应用窗口的根View,并提供一组通用的窗口操作接口。
    • DecorView类    该类是PhoneWindow类的内部类。该类是一个FrameLayout的子类,并且是PhoneWindow的子类,该类就是对普通的FrameLayout进行功能的扩展,更确切点可以说是修饰(Decor的英文全称是Decoration,即“修饰”的意思),比如说添加TitleBar(标题栏),以及TitleBar上的滚动条等 。最重要的一点是,它是所有应用窗口的根View 。

    打个不恰当比喻吧,Window类相当于一幅画(抽象概念,什么画我们未知) ,PhoneWindow为一副齐白石先生的山水画(具体概念,我们知道了是谁的、什么性质的画),DecorView则为该山水画的具体内容(有山、有水、有树,各种界面)。DecorView呈现在PhoneWindow上。

    当系统(一般是ActivityManagerService)配置好启动一个Activity的相关参数(包括Activity对象和Window对象信息)后,就会回调Activity的onCreate()方法,在其中我们通过设置setContentView()方法类设置该Activity的显示界面,整个调用链由此铺垫开来。setContentView()的三个构造方法调用流程本质上是一样的,我们就分析setContentView(intresId)方法。

    Activity.setContentView(intresId) 该方法在Activity类中,该方法只是简单的回调Window对象,具体为PhoneWindow对象的setContentView()方法实现。

    public void setContentView(int layoutResID) {  
        getWindow().setContentView(layoutResID);  
    }  
      
    public Window getWindow() {  
        return mWindow;   //Window对象,本质上是一个PhoneWindow对象  
    }  
    

    PhoneWindow.setContentView() 该方法在PhoneWindow类中

    @Override  
    public void setContentView(int layoutResID) {  
        //是否是第一次调用setContentView方法, 如果是第一次调用,则mDecor和mContentParent对象都为空  
        if (mContentParent == null) {  
            installDecor();  
        } else {  
            mContentParent.removeAllViews();  
        }  
        mLayoutInflater.inflate(layoutResID, mContentParent);  
        final Callback cb = getCallback();  
        if (cb != null) {  
            cb.onContentChanged();  
        }  
    }  
    

    该方法根据首先判断是否已经由setContentView()了获取mContentParent即View对象, 即是否是第一次调用该PhoneWindow对象setContentView()方法。如果是第一次调用,则调用installDecor()方法,否则,移除该mContentParent内所有的所有子View。最后将我们的资源文件通过LayoutInflater对象转换为View树,并且添加至mContentParent视图中。

    因此,在应用程序里,我们可以多次调用setContentView()来显示我们的界面。

更多 推荐条目

Welcome to NowaMagic Academy!

现代魔法 推荐于 2013-02-27 10:23   

本章最新发布
随机专题
  1. [移动开发] 使用support-v7 ActionBar前的那些坑 3 个条目
  2. [Python程序设计] Python语言概述 6 个条目
  3. [移动开发] Android 网络通信框架Volley 1 个条目
  4. [智力开发与知识管理] 整体性学习策略 9 个条目
  5. [移动开发] Android属性系统Property 9 个条目
  6. [搜索引擎优化] 与百度权重有关的信息 2 个条目
  7. [搜索引擎优化] 百度搜索引擎优化指南 3 个条目
  8. [Python程序设计] Tornado背景知识介绍 4 个条目
  9. [软件工程与项目管理] 呈现树的构建 13 个条目
  10. [Python程序设计] Django架构流程分析 7 个条目
  11. [JavaScript程序设计] 关于HTTP Keep-Alive 6 个条目
  12. [移动开发] Android Studio里的Gradle 3 个条目
窗口 -- [博客]