Android 中Activity,Window和View之间的关系
转自:http://hi.baidu.com/xiaofanqing/blog/item/8261ac114ab14f64cb80c435.html
我这里根据我个人的理解来讲讲我个人对这3个概念的理解。当然这里设计到通用的事件窗口模型等通用GUI设计,我这里就不打算讲了,纯粹从概念上来进行区分。
但在用户级别,程序员可能根愿意理解成为一个界面的载体。但仅仅是个载体,它本身并不负责任何绘制。Activity的内部实现,实际上是聚了一个 Window对象。Window是一个抽象类,它的具体是在android_src_home/framework/policies/base /phone/com/android/internal/policy/impl目录下的PhoneWindow.java。
下面是PhoneWindow中的setContentView方法的实现:
@Override
public void setContentView(View view, ViewGroup.LayoutParams params) {
if (mContentParent == null) {
installDecor();
else {
mContentParent.removeAllViews();
}
mContentParent.addView(view, params);
final Callback cb = getCallback();
if (cb != null) {
cb.onContentChanged();
}
}
Window内部首先判断mContentParent是否为空,然后调用installDecor方法(安装装饰器),我们看看这个方法如何实现的
private void installDecor() {
if (mDecor == null) {
mDecor = generateDecor();
true);
}
if (mContentParent == null) {
mContentParent = generateLayout(mDecor);
mTitleView = (TextView)findViewById(com.android.internal.R.id.title);
if (mTitleView != null) {
if ((getLocalFeatures() & (1 << FEATURE_NO_TITLE)) != 0) {
View titleContainer = findViewById(com.android.internal.R.id.title_container);
if (titleContainer != null) {
titleContainer.setVisibility(View.GONE);
else {
mTitleView.setVisibility(View.GONE);
}
if (mContentParent instanceof FrameLayout) {
null);
}
else {
mTitleView.setText(mTitle);
}
}
}
}
Activity--->Window--->DecorView
我们详细分析一下,类对象是如何被创建的。
Activity被创建后,系统会调用它的attach方法来将Activity添加到ActivityThread当中。我们找到Activity的attach方法如下:
final void attach(Context context, ActivityThread aThread,
int ident,
Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
Object lastNonConfigurationInstance,
HashMap<String,Object> lastNonConfigurationChildInstances,
Configuration config) {
attachBaseContext(context);
mWindow= PolicyManager.makeNewWindow(this);
mWindow.setCallback(this);
if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
mWindow.setSoftInputMode(info.softInputMode);
}
mUiThread = Thread.currentThread();
mMainThread = aThread;
mInstrumentation = instr;
mToken = token;
mIdent = ident;
mApplication = application;
mIntent = intent;
mComponent = intent.getComponent();
mActivityInfo = info;
mTitle = title;
mParent = parent;
mEmbeddedID = id;
mLastNonConfigurationInstance = lastNonConfigurationInstance;
mLastNonConfigurationChildInstances = lastNonConfigurationChildInstances;
mWindow.setWindowManager(null, mToken, mComponent.flattenToString());
if (mParent != null) {
mWindow.setContainer(mParent.getWindow());
}
mWindowManager = mWindow.getWindowManager();
mCurrentConfig = config;
}
我们看红色的代码部分,就是创建Window对象的代码。感兴趣的同学可以跟踪去看看具体是如何创建的。其实很简单,其内部实现调用了Policy对象的makeNewWindow方法,其方法直接new了一个PhoneWindow对象如下:
public PhoneWindow makeNewWindow(Context context) {
return new PhoneWindow(context);
}
这时我们已经可以把流程串起来,Activity创建后系统会调用其attach方法,将其添加到ActivityThread当中,在attach方法中创建了一个window对象。
我们回头看看Window实现里边的setContentView方法,我们看上面代码的红色部分setContentView-> installDecor-> generateDecor.
generateDecor直接new了一个DecorView对象:
protected DecorView generateDecor() {
return new DecorView(getContext(), -1);
}
我们可以去看看DecorView的实现,它是 PhoneWindow的一个内部类。实现很简单,它默认会包含一个灰色的标题栏,然后在标题栏下边会包含一个空白区域用来当用户调用 setContentView的时候放置用户View,并传递事件,这里不做详细分析,感兴趣同学可以自己研究研究。
当DecorView创建好之后再回到Window中的setContentView方法中来,见上面代码蓝色部分,调用
mContentParent.addView(view, params);
来将用户的View树添加到DecorView中。
现在总结一下:
Activity在onCreate之前调用attach方法,在attach方法中会创建window对象。window对象创建时并木有创建
Decor对象对象。用户在Activity中调用setContentView,然后调用window的setContentView,这时会检查
DecorView是否存在,如果不存在则创建DecorView对象,然后把用户自己的View 添加到DecorView中。
Android 中Activity,Window和View之间的关系的更多相关文章
- Android进阶笔记08:Android 中Activity、Window和View之间的关系
1. Android 中Activity.Window和View之间的关系(比喻): Activity像一个工匠(控制单元),Window像窗户(承载模型),View像窗花(显示视图) LayoutI ...
- Android 中的Activity、Window、View之间的关系
一.概述 Activity 可以说是应用程序的载体(也可以理解为界面的载体,但是不界面),用户能够在上面绘制界面(Activity本身不绘制界面),并提供用户处理事件的API,维护应用程序的生命周 ...
- android中activity,window,view之间的关系
activity:控制单元 window:承载模型 view:显示视图 几个小tip: 1.一个 Activity 构造的时候一定会构造一个 Window(PhoneWindow),并且只有一个 2. ...
- android中activity.this跟getApplicationContext的区别
转载: http://www.myexception.cn/android/1968332.html android中activity.this和getApplicationContext的区别 在a ...
- Android中Bitmap, Drawable, Byte,ID之间的转化
Android中Bitmap, Drawable, Byte,ID之间的转化 1. Bitmap 转化为 byte ByteArrayOutputStream out = new ByteArray ...
- Android中Activity启动模式详解
在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作.在Android中Activity的启动模式决定了Activity的启动运行方式. An ...
- 【转】Android中dip(dp)与px之间单位转换
Android中dip(dp)与px之间单位转换 dp这个单位可能对web开发的人比较陌生,因为一般都是使用px(像素)但是,现在在开始android应用和游戏后,基本上都转换成用dp作用为单位了,因 ...
- Android中Activity的启动模式
简介 Android中的活动启动方式分为4种:standard, singleTop, singleTask, singleInstance.可以在AndroidManifest.xml中通过给< ...
- 在Android中动画移动一个View的位置,采用Scroller类实现Android动画之 View移动
在Android中动画移动一个View的位置,采用Scroller类实现 今天说最近自己遇到的一个问题,就是要用动画效果来移动一个VIew的位置. 这个具体的情况是,需要做一个SlidingMenu的 ...
随机推荐
- npm更新和nodejs更新
npm更新和nodejs更新 更新你已经安装的NPM库,这个很简单,只需要运行. npm update -g 更新Nodejs自身.一直依赖我都是下载最新版的源码,然后make install,及其繁 ...
- error:No resource found that matches the given name 'Theme.AppCompat.Light'
一.stsckoverflow http://stackoverflow.com/questions/17870881/cant-find-theme-appcompat-light-for-new- ...
- dplyr快速入门
RStudio Blog 介绍dplyr 包已发布 (Introducing dplyr), 此包将原本 plyr 包中的 ddply() 等函数进一步分离强化, 专注接受dataframe对象, 大 ...
- 吴超老师课程--Hbase介绍和伪分布式安装
1.HBase(NoSQL)的数据模型1.1 表(table),是存储管理数据的.1.2 行键(row key),类似于MySQL中的主键. 行键是HBase表天然自带的.1.3 列族(col ...
- input和raw_input的区别
input会假设用户输入的是合法的Python表达式raw_input会把所有的输入当作原始数据,然后将其放入字符串中. 在最新的版本之中,input可以直接使用,替代了raw_input. 在2.7 ...
- Python(函数的参数)
函数参数的使用 def foo(x,y): pass foo(1,2) 形参:就是变量名 实参:就是变量值 形参:位置形参,默认参数,*args,命名关键字参数,**kwargs 实参: 按位置传值的 ...
- SSIS利用Microsoft Connector for Oracle by Attunity组件进行ETL!
对于BI项目,在数据仓库方面的技术实现主要是进行数据集成的工作,源数据可能来自不同的业务数据库(如Sql Server.ORACLE.My sql.EXCEL等),通过SSIS的数据流组件很容易进行各 ...
- NoSQL2
系统的可扩展性是推动NoSQL运动发展的的主要理由,包含了分布式系统协调,故障转移,资源管理和许多其他特性.这么讲使得NoSQL听起来像是一个大筐,什么都能塞进去.尽管NoSQL运动并没有给分布式数据 ...
- addEventListener和attachEvent介绍, 原生js和jquery的兼容性写法
也许很多同仁一听到事件监听,第一想到的就是原生js的 addEventListener()事件,的确如此,当然如果只是适用于现代浏览器(IE9.10.11 | ff, chorme, safari, ...
- hadoop28---netty传对象
Netty中,通讯的双方建立连接后,会把数据按照ByteBuf的方式进行传输,例如http协议中,就是通过HttpRequestDecoder对ByteBuf数据流进行处理,转换成http的对象.基于 ...