Android 四大组件之——Acitivity(四) Activity是如何加载显示内容的?
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是如何加载显示内容的?相关推荐
- Android 四大组件之——Acitivity(一)
一,什么是Activity activity是Android组件中最基本也是最为常见用的四大组件之一.Android四大组件有Activity,Service服务,Content Provider内容 ...
- Android 四大组件之——Acitivity(三) 深入了解Activity的启动流程
上图为整个Activity的启动流程 接下来我们大概分析 在我们的Android系统中,应用程序是由Launcher这个应用启动起来的.当我们安装好应用程序之后,就会在Launcher的界面上生成一个 ...
- Android进阶——Android四大组件启动机制之Activity启动过程
前言 Activity启动过程涉及到的比较多的知识点有Binder的跨进程通讯,建议先看完Binder的跨进程通讯再来阅读本篇文章,在文章阅读开始,我们先要理解Activity启动模型,再者去理解有关 ...
- Android动态listview,Android列表组件ListView使用详解之动态加载或修改列表数据
在使用ListView组件来显示列表数据时,有的时候我们需要改变列表中的数据,有以下方法: 1.重新给ListView组件设置适配器 这种方法重新创建了ListView,效率不好. 2.使用适配器中的 ...
- Android 四大组件之——Acitivity(二) 启动模式
Activity的启动模式共有4种 分别为 standard.singleTop.singleTask.singleInstance : 四种启动模式的配置都在Manifest文件中配置,配置模板 ...
- Android 四大组件之 Activity
什么是 Activity? Activity 是 Android 的四大组件之一,是用户操作的可视化界面,它为用户提供了一个完成操作指令的窗口. 当我们创建完 Activity 之后,需要调用 set ...
- android四大组件小整
原文来自http://www.jianshu.com/p/478a34af17df 所谓的android四大组件一次是Activity.Service.BroadcastReceiver和Conten ...
- Android 四大组件,五大存储,六大布局
Android 四大组件 android四大组件分别是:Activity, service,content provider,broadcast receiver 一.Activity 1.概念: a ...
- Android 四大组件基本介绍
1.基本概况 android 四大组件分别是 activity .service (服务).broadcast receiver(广播接收者).content provider(内容提供者). 2.a ...
最新文章
- 【Python-ML】SKlearn库Pipeline工作流和K折交叉验证
- Qt for Mac 设置软件开机自启动
- 写给大数据开发初学者的话5
- 在众多编程语言中,你可知哪种语言的安全性更高,安全漏洞最少?
- AutoCompleteTextView 和 TextWatcher 详解
- 2020年安卓学习笔记目录
- pip/pip3 install 报错 “Could not find a version that satisfies the requriement xxx” 的解决方法
- php判断直线相交,zoj 1158 判断2线段完全相交
- Dokcer学习笔记之Dokcerfile 文件构建
- 【狂神说Redis】2Redis入门 2-1概述
- 计算机械加工工时都需要,机械加工工时(工时定额)计算软件
- zmap扫描mysql_基于zmap 的应用层扫描器 zgrab (一)
- vscode连接夜神模拟器
- jack分享的1-3开wifi 零火版本智能开关解决方案
- MySQL命令简单应用
- 金庸笔下人物以及网络俏皮英语对应关系表-诗词
- 数据库应用(mysql)数据库管理
- kali永久提root权限
- 任性杭州,骨感北京——面试汇总
- 正则表达式常用验证及打油诗一首
热门文章
- 只能数字或小数 只能有一个小数点并且第一位不能为小数点,还有小数点后面限制两位
- JAVA 条件语句 跟PHP没有区别!!!!!
- Windows上部署Ngnix
- windows下编译jsoncpp 1.y.z
- javascript正则表达式验证密码(必须含数字字符特殊符号,长度4-16位之间)
- Mariadb修改root密码
- webpack学习笔记 (三) webpack-dev-server插件和HotModuleReplacementPlugin插件使用
- [bzoj2324][ZJOI2011]营救皮卡丘
- UITableViewCell 添加长按手势
- uva 11020 - Efficient Solutions