Android 中的Activity、Window、View之间的关系
2016-01-19 12:21
519 查看
一、概述
Activity 可以说是应用程序的载体(也可以理解为界面的载体,但是不界面),用户能够在上面绘制界面(Activity本身不绘制界面),并提供用户处理事件的API,维护应用程序的生命周期(Android应用程序是由多个 Activity 堆积而成,而各个 Activity 又有其独立的生命周期)。
Activity内部组合了一个Window(这是一个抽象类,具体是PhoneWindow)对象。我们自己写的扩展一个Activity时,在onCreate 方法中调用 setContentView,实际上是调用Window对象的 setContentView,所以说界面绘制全部是由Window类的实现类(PhoneWindow类)来完成的。
二、源码分析
1. 跟踪源码进入到 Activity 中看到 setContentView的实现如下:
看第二行代码,先得到一个 Window 对象。
getWindow 很简单只是返回一个 对象而已,那么,Window对象到底是在哪儿实例化的呢?
我们可以看看,Activity 中的 attach 方法,这里面得到了一个 Window 对象
2. 由Activity中的 setContentView 方法可以看到,界面绘制并不是由 Activity 完成的,他是调用了 Window 类的 setContentView 来实现的。所以我们就去看看 Window 类的代码:
我们可以看到, Window 类是一个抽象类,并且 setContentView 是一个抽象方法。所以说,其具体实现是由 实现 Window类的类来完成的(PhoneWindow)。
3. 在文档中已经描述了:The only existing implementation of this abstract class is android.policy.PhoneWindow. 我们要来看看这个类才能知道 界面是如何完成绘制的。
先判断mContentParent是否为空,如果为空就调用 installDecor 方法(自己可以看一下源码), 最后会添加 View。
Window 中有一个 DecorView,可以理解为“ViewRoot”,引号是说其实这个“ViewRoot”是一个View或者说ViewGroup,是最初始的根视图。构建视图就是向这里面添加。所以到这里大概可以知道,installDecor 方法大概是 构建一个根视图。
三、总结
![](http://images2015.cnblogs.com/blog/491713/201601/491713-20160119120248187-853146836.png)
Activity创建时系统会调用其 attach 方法,将其添加到ActivityThread当中,在attach方法中创建了一个window对象。
我们知道Window组合了一个 DocerView, 当用户调用 setContentView 的时候会把一棵 View 树仍给DocerView。 View树是已经创建好的实例对象,所以我们要研究 DocerView是个什么东西,它是如何被创建的。
我们回头看看Window实现里边的setContentView方法,代码中有一个 installDecor 方法,这个方法中有一个 generateDecor。 generateDecor直接new了一个DecorView对象
当 DocerView 被创建后,就会调用 mContentParent.addView(view, params); 来将 view 添加到 DocerView当中。
最后总结一下:
Activity在onCreate时调用attach方法,在attach方法中会创建window对象。window对象创建时并没有创建 DocerView 对象。用户在Activity中调用setContentView,然后调用window的setContentView,这时会检查DecorView是否存在,如果不存在则创建DecorView对象,然后把用户自己的 View 添加到 DecorView 中。
装模作样的声明一下:本博文章若非特殊注明皆为原创,若需转载请保留原文链接(/article/5257283.html)及作者信息k_est
Activity 可以说是应用程序的载体(也可以理解为界面的载体,但是不界面),用户能够在上面绘制界面(Activity本身不绘制界面),并提供用户处理事件的API,维护应用程序的生命周期(Android应用程序是由多个 Activity 堆积而成,而各个 Activity 又有其独立的生命周期)。
Activity内部组合了一个Window(这是一个抽象类,具体是PhoneWindow)对象。我们自己写的扩展一个Activity时,在onCreate 方法中调用 setContentView,实际上是调用Window对象的 setContentView,所以说界面绘制全部是由Window类的实现类(PhoneWindow类)来完成的。
二、源码分析
1. 跟踪源码进入到 Activity 中看到 setContentView的实现如下:
public void setContentView(int layoutResID) { getWindow().setContentView(layoutResID); initActionBar(); }
看第二行代码,先得到一个 Window 对象。
public Window getWindow() { return mWindow; }
getWindow 很简单只是返回一个 对象而已,那么,Window对象到底是在哪儿实例化的呢?
我们可以看看,Activity 中的 attach 方法,这里面得到了一个 Window 对象
mWindow = PolicyManager.makeNewWindow(this);
2. 由Activity中的 setContentView 方法可以看到,界面绘制并不是由 Activity 完成的,他是调用了 Window 类的 setContentView 来实现的。所以我们就去看看 Window 类的代码:
public abstract void setContentView(int layoutResID);
我们可以看到, Window 类是一个抽象类,并且 setContentView 是一个抽象方法。所以说,其具体实现是由 实现 Window类的类来完成的(PhoneWindow)。
3. 在文档中已经描述了:The only existing implementation of this abstract class is android.policy.PhoneWindow. 我们要来看看这个类才能知道 界面是如何完成绘制的。
@Override public void addContentView(View view, ViewGroup.LayoutParams params) { if (mContentParent == null) { installDecor(); } if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) { // TODO Augment the scenes/transitions API to support this. Log.v(TAG, "addContentView does not support content transitions"); } mContentParent.addView(view, params); final Callback cb = getCallback(); if (cb != null && !isDestroyed()) { cb.onContentChanged(); } }
先判断mContentParent是否为空,如果为空就调用 installDecor 方法(自己可以看一下源码), 最后会添加 View。
Window 中有一个 DecorView,可以理解为“ViewRoot”,引号是说其实这个“ViewRoot”是一个View或者说ViewGroup,是最初始的根视图。构建视图就是向这里面添加。所以到这里大概可以知道,installDecor 方法大概是 构建一个根视图。
三、总结
![](http://images2015.cnblogs.com/blog/491713/201601/491713-20160119120248187-853146836.png)
Activity创建时系统会调用其 attach 方法,将其添加到ActivityThread当中,在attach方法中创建了一个window对象。
我们知道Window组合了一个 DocerView, 当用户调用 setContentView 的时候会把一棵 View 树仍给DocerView。 View树是已经创建好的实例对象,所以我们要研究 DocerView是个什么东西,它是如何被创建的。
我们回头看看Window实现里边的setContentView方法,代码中有一个 installDecor 方法,这个方法中有一个 generateDecor。 generateDecor直接new了一个DecorView对象
protected DecorView generateDecor() { return new DecorView(getContext(), -1); }
当 DocerView 被创建后,就会调用 mContentParent.addView(view, params); 来将 view 添加到 DocerView当中。
最后总结一下:
Activity在onCreate时调用attach方法,在attach方法中会创建window对象。window对象创建时并没有创建 DocerView 对象。用户在Activity中调用setContentView,然后调用window的setContentView,这时会检查DecorView是否存在,如果不存在则创建DecorView对象,然后把用户自己的 View 添加到 DecorView 中。
装模作样的声明一下:本博文章若非特殊注明皆为原创,若需转载请保留原文链接(/article/5257283.html)及作者信息k_est
相关文章推荐
- 怎样获取android手机联系人并按字母展示(一)
- android ndk搭建以及JNI的Helloworld编写
- android 工作笔记 内存优化问题
- G面经prepare: Android Phone Unlock Pattern
- android 蓝牙 搜索匹配
- Android软键盘弹出时把布局顶上去的解决方法 .
- android Activity关闭动画 附左右动画anim
- android TextView的注意事项
- 【Android】如何查看Activity Task栈的情况
- Android-Universal-Image-Loader 使用
- Picasso-Android图片缓存库
- Android基础类之BaseAdapter
- Android 获取包名,版本信息及VersionName名称
- 疑问一
- Android中EditText+Button组合导致输入板无法收起的原因分析及解决办法
- android学习笔记
- android 图片处理工具
- Android 讲解:数据共享
- Android ButterKnife注解式开发
- android dialog宽度无法填满屏幕解决方案