1. 在Activity调用onCreate()等生命周期之前,Activity会调用attach()方法,而在attach()方法中会调用如下代码

onAttach()
{PolicyManager.makeNewWindow(this)
}

而makeNewWindow实际上时创建 Window的子类PhoneWindow,也就是说在调用onCreate()方法之前, Activity会首先创建一个PhoneWindow,用于管理显示内容的容器

2.创建了窗体之后,Activity调用onCreate()方法,以下是我们司空见惯的代码

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);}

3.在Activity的setContentview()方法里,会调用如下PhoneWindow的setContentview()

public void setContentView(View view,ViewGroup.LayoutParams params)
{getWindow().setContentview(view,params);
}

getWindow() 实际上返回的是刚开始创建的PhoneWinow

4.执行PhoneWindow  的setContentView()

@Override  public void setContentView(int layoutResID) {  if (mContentParent == null) {  installDecor();      //如果mContentParent为null,则创建容器} else {  mContentParent.removeAllViews(); //如果不为空,则清除容器上所有内容}  mLayoutInflater.inflate(layoutResID, mContentParent); //然后在容器上填充布局内容 final Callback cb = getCallback();  if (cb != null) {  cb.onContentChanged();  }  }  

installDecor(),究竟创建了一个什么样的容器呢?

 private void installDecor() {  if (mDecor == null) {  mDecor = generateDecor();mDecor.setIsRootNamespace(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) {  ((FrameLayout)mContentParent).setForeground(null);  }  } else {  mTitleView.setText(mTitle);  }  }  }  }  

generateLayout(DecorView decor)又会返回什么呢?

 protected ViewGroup generateLayout(DecorView decor) {  // Apply data from current theme.  TypedArray a = getWindowStyle();  if (false) {  System.out.println("From style:");  String s = "Attrs:";  for (int i = 0; i < com.android.internal.R.styleable.Window.length; i++) {  s = s + " " + Integer.toHexString(com.android.internal.R.styleable.Window[i]) + "="  + a.getString(i);  }  System.out.println(s);  }  mIsFloating = a.getBoolean(com.android.internal.R.styleable.Window_windowIsFloating, false);  int flagsToUpdate = (FLAG_LAYOUT_IN_SCREEN|FLAG_LAYOUT_INSET_DECOR)  & (~getForcedWindowFlags());  if (mIsFloating) {  setLayout(WRAP_CONTENT, WRAP_CONTENT);  setFlags(0, flagsToUpdate);  } else {  setFlags(FLAG_LAYOUT_IN_SCREEN|FLAG_LAYOUT_INSET_DECOR, flagsToUpdate);  }  if (a.getBoolean(com.android.internal.R.styleable.Window_windowNoTitle, false)) {  requestFeature(FEATURE_NO_TITLE);  }  if (a.getBoolean(com.android.internal.R.styleable.Window_windowFullscreen, false)) {  setFlags(FLAG_FULLSCREEN, FLAG_FULLSCREEN&(~getForcedWindowFlags()));  }  WindowManager.LayoutParams params = getAttributes();  if (!hasSoftInputMode()) {  params.softInputMode = a.getInt(  com.android.internal.R.styleable.Window_windowSoftInputMode,  params.softInputMode);  }  if (a.getBoolean(com.android.internal.R.styleable.Window_backgroundDimEnabled,  mIsFloating)) {  /* All dialogs should have the window dimmed */  if ((getForcedWindowFlags()&WindowManager.LayoutParams.FLAG_DIM_BEHIND) == 0) {  params.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;  }  params.dimAmount = a.getFloat(  android.R.styleable.Window_backgroundDimAmount, 0.5f);  }  if (params.windowAnimations == 0) {  params.windowAnimations = a.getResourceId(  com.android.internal.R.styleable.Window_windowAnimationStyle, 0);  }  // The rest are only done if this window is not embedded; otherwise,  // the values are inherited from our container.  if (getContainer() == null) {  if (mBackgroundDrawable == null) {  if (mBackgroundResource == 0) {  mBackgroundResource = a.getResourceId(  com.android.internal.R.styleable.Window_windowBackground, 0);  }  if (mFrameResource == 0) {  mFrameResource = a.getResourceId(com.android.internal.R.styleable.Window_windowFrame, 0);  }  if (false) {  System.out.println("Background: "  + Integer.toHexString(mBackgroundResource) + " Frame: "  + Integer.toHexString(mFrameResource));  }  }  mTextColor = a.getColor(com.android.internal.R.styleable.Window_textColor, 0xFF000000);  }  // Inflate the window decor.  int layoutResource;  int features = getLocalFeatures();  // System.out.println("Features: 0x" + Integer.toHexString(features));  if ((features & ((1 << FEATURE_LEFT_ICON) | (1 << FEATURE_RIGHT_ICON))) != 0) {  if (mIsFloating) {  layoutResource = com.android.internal.R.layout.dialog_title_icons;  } else {  layoutResource = com.android.internal.R.layout.screen_title_icons;  }  // System.out.println("Title Icons!");  } else if ((features & ((1 << FEATURE_PROGRESS) | (1 << FEATURE_INDETERMINATE_PROGRESS))) != 0) {  // Special case for a window with only a progress bar (and title).  // XXX Need to have a no-title version of embedded windows.  layoutResource = com.android.internal.R.layout.screen_progress;  // System.out.println("Progress!");  } else if ((features & (1 << FEATURE_CUSTOM_TITLE)) != 0) {  // Special case for a window with a custom title.  // If the window is floating, we need a dialog layout  if (mIsFloating) {  layoutResource = com.android.internal.R.layout.dialog_custom_title;  } else {  layoutResource = com.android.internal.R.layout.screen_custom_title;  }  } else if ((features & (1 << FEATURE_NO_TITLE)) == 0) {  // If no other features and not embedded, only need a title.  // If the window is floating, we need a dialog layout  if (mIsFloating) {  layoutResource = com.android.internal.R.layout.dialog_title;  } else {  layoutResource = com.android.internal.R.layout.screen_title;  }  // System.out.println("Title!");  } else {  // Embedded, so no decoration is needed.  layoutResource = com.android.internal.R.layout.screen_simple;  // System.out.println("Simple!");  }  mDecor.startChanging();  View in = mLayoutInflater.inflate(layoutResource, null);  decor.addView(in, new ViewGroup.LayoutParams(FILL_PARENT, FILL_PARENT));  ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);if (contentParent == null) {  throw new RuntimeException("Window couldn't find content container view");  }  if ((features & (1 << FEATURE_INDETERMINATE_PROGRESS)) != 0) {  ProgressBar progress = getCircularProgressBar(false);  if (progress != null) {  progress.setIndeterminate(true);  }  }  // Remaining setup -- of background and title -- that only applies  // to top-level windows.  if (getContainer() == null) {  Drawable drawable = mBackgroundDrawable;  if (mBackgroundResource != 0) {  drawable = getContext().getResources().getDrawable(mBackgroundResource);  }  mDecor.setWindowBackground(drawable);  drawable = null;  if (mFrameResource != 0) {  drawable = getContext().getResources().getDrawable(mFrameResource);  }  mDecor.setWindowFrame(drawable);  // System.out.println("Text=" + Integer.toHexString(mTextColor) +  // " Sel=" + Integer.toHexString(mTextSelectedColor) +  // " Title=" + Integer.toHexString(mTitleColor));  if (mTitleColor == 0) {  mTitleColor = mTextColor;  }  if (mTitle != null) {  setTitle(mTitle);  }  setTitleColor(mTitleColor);  }  mDecor.finishChanging();  return contentParent;  }  

代码比较多,我们抓重点来看,即标记为红色部分,从上面可以看出,最终是以 decor 为容器

最后用一张关系图来总结一下Activity加载显示内容的过程

Android 四大组件之——Acitivity(四) Activity是如何加载显示内容的?相关推荐

  1. Android 四大组件之——Acitivity(一)

    一,什么是Activity activity是Android组件中最基本也是最为常见用的四大组件之一.Android四大组件有Activity,Service服务,Content Provider内容 ...

  2. Android 四大组件之——Acitivity(三) 深入了解Activity的启动流程

    上图为整个Activity的启动流程 接下来我们大概分析 在我们的Android系统中,应用程序是由Launcher这个应用启动起来的.当我们安装好应用程序之后,就会在Launcher的界面上生成一个 ...

  3. Android进阶——Android四大组件启动机制之Activity启动过程

    前言 Activity启动过程涉及到的比较多的知识点有Binder的跨进程通讯,建议先看完Binder的跨进程通讯再来阅读本篇文章,在文章阅读开始,我们先要理解Activity启动模型,再者去理解有关 ...

  4. Android动态listview,Android列表组件ListView使用详解之动态加载或修改列表数据

    在使用ListView组件来显示列表数据时,有的时候我们需要改变列表中的数据,有以下方法: 1.重新给ListView组件设置适配器 这种方法重新创建了ListView,效率不好. 2.使用适配器中的 ...

  5. Android 四大组件之——Acitivity(二) 启动模式

    Activity的启动模式共有4种 分别为   standard.singleTop.singleTask.singleInstance : 四种启动模式的配置都在Manifest文件中配置,配置模板 ...

  6. Android 四大组件之 Activity

    什么是 Activity? Activity 是 Android 的四大组件之一,是用户操作的可视化界面,它为用户提供了一个完成操作指令的窗口. 当我们创建完 Activity 之后,需要调用 set ...

  7. android四大组件小整

    原文来自http://www.jianshu.com/p/478a34af17df 所谓的android四大组件一次是Activity.Service.BroadcastReceiver和Conten ...

  8. Android 四大组件,五大存储,六大布局

    Android 四大组件 android四大组件分别是:Activity, service,content provider,broadcast receiver 一.Activity 1.概念: a ...

  9. Android 四大组件基本介绍

    1.基本概况 android 四大组件分别是 activity .service (服务).broadcast receiver(广播接收者).content provider(内容提供者). 2.a ...

最新文章

  1. 【Python-ML】SKlearn库Pipeline工作流和K折交叉验证
  2. Qt for Mac 设置软件开机自启动
  3. 写给大数据开发初学者的话5
  4. 在众多编程语言中,你可知哪种语言的安全性更高,安全漏洞最少?
  5. AutoCompleteTextView 和 TextWatcher 详解
  6. 2020年安卓学习笔记目录
  7. pip/pip3 install 报错 “Could not find a version that satisfies the requriement xxx” 的解决方法
  8. php判断直线相交,zoj 1158 判断2线段完全相交
  9. Dokcer学习笔记之Dokcerfile 文件构建
  10. 【狂神说Redis】2Redis入门 2-1概述
  11. 计算机械加工工时都需要,机械加工工时(工时定额)计算软件
  12. zmap扫描mysql_基于zmap 的应用层扫描器 zgrab (一)
  13. vscode连接夜神模拟器
  14. jack分享的1-3开wifi 零火版本智能开关解决方案
  15. MySQL命令简单应用
  16. 金庸笔下人物以及网络俏皮英语对应关系表-诗词
  17. 数据库应用(mysql)数据库管理
  18. kali永久提root权限
  19. 任性杭州,骨感北京——面试汇总
  20. 正则表达式常用验证及打油诗一首

热门文章

  1. 只能数字或小数 只能有一个小数点并且第一位不能为小数点,还有小数点后面限制两位
  2. JAVA 条件语句 跟PHP没有区别!!!!!
  3. Windows上部署Ngnix
  4. windows下编译jsoncpp 1.y.z
  5. javascript正则表达式验证密码(必须含数字字符特殊符号,长度4-16位之间)
  6. Mariadb修改root密码
  7. webpack学习笔记 (三) webpack-dev-server插件和HotModuleReplacementPlugin插件使用
  8. [bzoj2324][ZJOI2011]营救皮卡丘
  9. UITableViewCell 添加长按手势
  10. uva 11020 - Efficient Solutions