android 加载过程,Android View (2) View的加载过程
View的加载过程
android 在加载视图的过程是通过在Activity的 setContentView(@LayoutRes int layoutResID) 来加载的,我们通过分析源码(在线源码链接)过程来理解。
setContentView(int layoutResID)源码分析
上篇我们说过WindowPhone类继承了Window类,Window类只是定义了一些方法和规范,所以我们直接看WindowPhone类中的方法。有三个重载方法,我们只分析一个,代码如下:
@Override
public void setContentView(int layoutResID) {
// Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window
// decor, when theme attributes and the like are crystalized. Do not check the feature
// before this happens.
//判断是否第一次进入
if (mContentParent == null) {
//创建DecorView,并添加布局到mContentParent
installDecor();
//hasFeature(FEATURE_CONTENT_TRANSITIONS)是否设置了过场动画
} else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
//清空之前的View
mContentParent.removeAllViews();
}
if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
//通过Scene执行过场动画(执行过程中会清空之前的View和添加新的布局)
final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID,
getContext());
transitionTo(newScene);
} else {
//向mContentParent添加布局
mLayoutInflater.inflate(layoutResID, mContentParent);
}
mContentParent.requestApplyInsets();
final Callback cb = getCallback();
if (cb != null && !isDestroyed()) {
//回调通知表示完成界面加载
cb.onContentChanged();
}
// Whether the client has explicitly set the content view. If false and mContentParent is notnull, then the content parent was set due to window preservation.
//是否显式的设置了视图
mContentParentExplicitlySet = true;
}
接下来看installDecor() 代码如下:
private void installDecor() {
2640 mForceDecorInstall = false;
// 如果mDecor为空,则生成一个Decor,并设置其属性
2641 if (mDecor == null) {
// System process doesn't have application context and in that case we need to directly use the context we have.
// Otherwise we want the application context, so we don't cling to the activity.
//generateDecor()主要用于创建Decor且不依赖与Activity
2642 mDecor = generateDecor(-1);
//设置父View 与子View的聚焦关系
2643 mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
// 设置mDecor为整个Activity窗口的根节点,从此处可以看出窗口根节点为一个DecorView
2644 mDecor.setIsRootNamespace(true);
// 满足条件执行动画操作
2645 if (!mInvalidatePanelMenuPosted && mInvalidatePanelMenuFeatures != 0) {
2646 mDecor.postOnAnimation(mInvalidatePanelMenuRunnable);
2647 }
2648 } else {
2649 mDecor.setWindow(this);
2650 }
2651 if (mContentParent == null) {
//根据窗口的风格修饰,选择对应的修饰布局文件,并且将id为content的FrameLayout赋值给mContentParent
2652 mContentParent = generateLayout(mDecor);
2653
2654 // Set up decor part of UI to ignore fitsSystemWindows if appropriate.
2655 mDecor.makeOptionalFitsSystemWindows();
2656 //获取DecorView顶级布局,提供一些设置title,window主题等的方法
2657 final DecorContentParent decorContentParent = (DecorContentParent) mDecor.findViewById(
2658 R.id.decor_content_parent);
2659
2660 if (decorContentParent != null) {
2661 //1. 将decorContentParent赋值给mDecorContentParent
//2. 设置窗口回调函数
//3.设置窗口的title、icon、logo等属性值
2699 } else {
2700 mTitleView = findViewById(R.id.title);
//这里有一个我们日常使用的ActionBar是否显示的判断,所以我们的设置要在setContentView方法之前
2701 if (mTitleView != null) {
2702 if ((getLocalFeatures() & (1 << FEATURE_NO_TITLE)) != 0) {
2703 final View titleContainer = findViewById(R.id.title_container);
2704 if (titleContainer != null) {
2705 titleContainer.setVisibility(View.GONE);
2706 } else {
2707 mTitleView.setVisibility(View.GONE);
2708 }
2709 mContentParent.setForeground(null);
2710 } else {
2711 mTitleView.setText(mTitle);
2712 }
2713 }
2714 }
2715
2716 if (mDecor.getBackground() == null && mBackgroundFallbackResource != 0) {
2717 mDecor.setBackgroundFallback(mBackgroundFallbackResource);
2718 }
2719 //....好多关于背景,动画等的判断,省略
2770 }
2771 }
2772 }
2773 }
接下来分析generateLayout(DecorView decor)方法的源码
//返回当前Activity的内容区域视图,即我们的布局文件显示区域mContentParent
protected ViewGroup generateLayout(DecorView decor) {
2309 // Apply data from current theme.
2310 //获取属性值
2311 TypedArray a = getWindowStyle();
2312 //根据Them来设置或修改各种属性,选定不同的资源文件等
.......
//设置title和background属性
2627 }
2628
2629 mDecor.finishChanging();
2630
2631 return contentParent;
2632 }
其实在geneateLayout中会根据我们在清单文件中设置的主题来进行加载相应的主题,布局等等。
总结
梳理setContentView()加载布局的过程:首先如果是首次调用的话,我们会创建DecorView对象作为Activity根视图,如果不是第一次调用,我们只需要移除之前的布局,继续用DecorView对象去作为根视图, 在加载布局过程中会通过设置的ThemStyle 设置一些属性值,然后通过findviewbyid的方式将跟布局文件添加到DecorView中,然后通过回调Activity的onContentChanged方法,通知布局加载完成
在加载View的过程中,系统是通过递归遍历一步步的进行解析加载的,所以我们在开发中,尽量不要嵌套太多层的布局,会影响到布局的加载效率,可以通过merge标签来减少嵌套层数。
参考
android 加载过程,Android View (2) View的加载过程相关推荐
- android 自定义view 动画效果,Android自定义view实现阻尼效果的加载动画
效果: 需要知识: 1. 二次贝塞尔曲线 2. 动画知识 3. 基础自定义view知识 先来解释下什么叫阻尼运动 阻尼振动是指,由于振动系统受到摩擦和介质阻力或其他能耗而使振幅随时间逐渐衰减的振动,又 ...
- android 自定义view 加载图片,Android自定义View基础开发之图片加载进度条
学会了Paint,Canvas的基本用法之后,我们就可以动手开始实践了,先写个简单的图片加载进度条看看. 按照惯例,先看效果图,再决定要不要往下看: 既然看到这里了,应该是想了解这个图片加载进度条了, ...
- android viewpager动态加载页面,Android viewpager中动态添加view并实现伪无限循环的方法...
本文实例讲述了Android viewpager中动态添加view并实现伪无限循环的方法.分享给大家供大家参考,具体如下: viewpager的使用,大家都熟悉,它可以实现页面之间左右滑动的切换,这里 ...
- android 加载layout,Android自定义View加载视图之LoadingLayout
介绍 上一篇博文写了一个通用的加载view,这篇在加载view的基础在包裹一层就是LoadingLayout了,主要的目的是免去每次加载时要隐藏主内容布局,然后加载成功之后显示主内容布局这些繁琐操作. ...
- android 动画间隔时间,Android使用View Animation实现动画加载界面
之前分别介绍了View Animation和Drawable Animation,学了就要用啊,今天给大家一个使用View Animation实现动画加载界面的实现. 首先先看一下实现效果. 下面是实 ...
- android 自定义加载动画效果,Android自定义View实现loading动画加载效果
项目开发中对Loading的处理是比较常见的,安卓系统提供的不太美观,引入第三发又太麻烦,这时候自己定义View来实现这个效果,并且进行封装抽取给项目提供统一的loading样式是最好的解决方式了. ...
- 【Android 性能优化】布局渲染优化 ( GPU 过度绘制优化总结 | CPU 渲染过程 | Layout Inspector 工具 | View Tree 分析 | 布局组件层级分析 )
文章目录 一. GPU 过度绘制优化总结 二. CPU 渲染过程 三. CPU 渲染性能调试工具 Layout Inspector 四. Layout Inspector 组件树 DecorView ...
- android显示过程,Android 桌面加载图标过程分析
桌面应用图标流程 前言 本人工作上碰到这么一个需求,开发一款滤镜引擎,将桌面上所有的图标进行统一的滤镜化,这就需要了解一下整个桌面去取图标的过程,了解了整个过程,找到真正拿图标的地方,在真正取图标的地 ...
- Android View的工作流程(二) measure过程
一.View的measure过程 View的measure过程是由View的measure方法完成的,他是一个被final关键字修饰的方法,我们无法重写该方法,但是measure方法中会调用onMe ...
- 【Android View绘制之旅】Draw过程
出效果:绘制 经过前面的准备工作 :[Android View绘制之旅]Measure过程,[Android View绘制之旅]Layout过程 我们的视图具备了宽高数据,位置数据,现在到了激动人心的 ...
最新文章
- Python collections 模块 namedtuple、Counter、defaultdict
- 小程序仿安卓动画滑动效果滑动动画效果实现
- 常用的JQuery数字类型验证正则表达式
- phpcms 前台模板替换成官网类型的网站
- GDCM:gdcm::ByteBuffer的测试程序
- SQL Server代理(4/12):配置数据库邮件
- mongodb及其索引的使用例子
- c语言数字排列和算法思路,冒泡排序、快速排序算法理解及C程序实现
- JS !(非运算)详解
- redis aof 备份和恢复_深入理解Redis持久化
- 计算机图形学多边形填充代码_计算机图形学 Computer Graphics (第一周笔记及课件翻译)...
- 详细介绍svn在eclipse中的使用(附图解说明)
- Chrome主页被恶意篡改
- Java学习实战教程之mysql优化
- php控制步进电机,步进电机的速度控制的原理及方法简介
- swper_Swiper 中文API手册(share)
- 第一篇文献:谈大数据时代的云控制摄影测量 ——张祖勋院士
- mysql timestamp 差值_SQL计算timestamp的差值实例分享
- 高德定位SDK踩坑-高精度模式下获取不到GPS定位(无网络环境)
- OFDM载波间隔_OFDM基本参数选择
热门文章
- (转)优秀的创始人不是知道一切,而是学习一切
- (转)Rust:Vec、String 内存布局
- 阿里云丁宇:阿里巴巴15年云原生实践
- 阿里云为自动驾驶量身打造一体化解决方案,助力行业突破技术瓶颈
- 机器学习笔记(二十):逻辑回归(2)
- pyqt 子窗口控制主窗口绘图_PyQtGraph如何关闭绘图窗口/关闭所有绘图窗口?
- 【故障分析】基于matlab ICA故障监测【含Matlab源码 1590期】
- 【元胞自动机】基于matlab激进策略元胞自动机三车道(开放辅路,软件园影响)交通流模型【含Matlab源码 1298期】
- uni 登录token方法_uniapp如何检验用户是否登录
- linux多进程通过中断实现,关于Linux内核源码中是如何区别进程上下文和中断上下文...