源码分析 | Activity-setContentView

简介: 普通的一个 Activity-setContentView(),你知道它内部做了什么吗?

引言

普通的一个 Activity-setContentView(),你知道它内部做了什么吗?

概要

源码分析

我们先来看一下Activity-setContentView方法:

public void setContentView(@LayoutRes int layoutResID) {
    getWindow().setContentView(layoutResID);
    initWindowDecorActionBar();
}

简简单单滴方法,内部调用了 getWindows.setContentView(xxx)

等等,Windows 是什么?

Windows 表示一个窗口的概念,Android 中不管是Activity,dialog,还是 Toast 它们的视图都是附加在 Windows 上,因此可以称 windows 是View的直接管理者。而Windows也只有实现类,即PhoneWindows.

我们接着去看 PhoneWindowssetContentView()

@Override
public void setContentView(int layoutResID) {
    if (mContentParent == null) {
        installDecor(); //关注点
    } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
        mContentParent.removeAllViews();
    }
     mLayoutInflater.inflate(layoutResID, mContentParent);
}

简简单单,内部执行了一个判断,然后调用 **installDecor() ** 方法。

等等,mContenParent是什么?

mContentParent 即放置我们自己布局的容器,你可以理解为,它是我们的根布局,详情看图。

我们接着去看 installDecor() 方法:

private void installDecor() {
    ...忽略掉
    mDecor = generateDecor(-1); //关注点1
    ...忽略掉
    if (mContentParent == null) {
      //关注点2
      mContentParent = generateLayout(mDecor);
    }
    ...忽略掉一大段
}

这个方法内部很繁琐,很臭很长,我们需要关注这么多吗,不需要,所以直接先进入 generateDecor().

等等,mDecor 是什么?

mDecor 是 windows 唯一视图,也就是我们 mContentParent 的爸爸。简称 DecorView,是不是回忆起了点什么。

我们接着去看 generateDecor() 方法

protected DecorView generateDecor(int featureId) {
    ...忽略一大段
    return new DecorView(context, featureId, this, getAttributes());
}

哇,这个方法爱了爱了,直接new了一个 DecorView,其他也没啥,返回回去看 installDecor() 中的关注点2-generateLayout().


我们进入 generateLayout() 方法:

protected ViewGroup generateLayout(DecorView decor) {
   //1
   TypedArray a = getWindowStyle();
   if(xx)else if(xxx) 
   else {
       layoutResource = R.layout.screen_simple;
   }
   //2
   mDecor.onResourcesLoaded(mLayoutInflater, layoutResource);
   ..忽略掉一部分
   //3
   ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
   return contentParent;
}
  1. 显示获取当前主题,然后开始判断究竟要用那个布局
  2. 将其加载到 DecorView
  3. 通过 findViewById(内部就是DecorView.findViewById)获取 R.id.content,并返回此viewGroup。

等等,这个 R.layout.screen_simple 是甚?



哦,就一个普通的布局,没什么太奇怪的。

串一遍思路

我们接下来将上面的分析整体走一遍:

  • 当我们调用Activity的 setContentView 时,内部其实是执行了 PhoneWindows(windows的唯一实例)的 setContenView()
  • PhoneWindowssetContentView() 内部会先判断当前有没有根布局 contentParent,也即就是有没有 DecorView,如果没有,执行 installDecor() 去初始化我们的 DecorViewcontentParent
  • installDecor() 方法里面,会先判断有没有 DecorView,如果没有,先new一个出来,然后判断有没有 contentParent,没有的话,就去根据当前主题,选择一个布局,并将其当做我们的根布局添加到 DecorView 中;
  • 最后 PhoneWindows-setContentView() 方法接下来就可以将我们自己的布局 inflate 进这个根布局里了;
目录
相关文章
|
程序员 Shell Linux
01 python - 历史起源
01 python - 历史起源
255 0
|
数据采集 机器学习/深度学习 存储
【机器学习】数据清洗——基于Numpy库的方法删除重复点
【机器学习】数据清洗——基于Numpy库的方法删除重复点
461 1
|
存储 SQL JSON
信创迁移适配实战-MySQL到达梦数据库DM8的数据迁移
信创迁移适配实战-MySQL到达梦数据库DM8的数据迁移
6633 0
信创迁移适配实战-MySQL到达梦数据库DM8的数据迁移
|
11月前
|
机器人 计算机视觉 Python
Python作为一种高效、易读且功能强大的编程语言,在教育领域的应用日益广泛
Python作为一种高效、易读且功能强大的编程语言,在教育领域的应用日益广泛
240 5
|
存储 数据挖掘 API
DPDK_Hash(1)
DPDK_Hash(1)
362 0
|
7月前
|
JavaScript 前端开发 Java
Idea启动SpringBoot程序报错:Veb server failed to start. Port 8082 was already in use;端口冲突的原理与解决方案
本文解决了Idea启动SpringBoot程序报错:Veb server failed to start. Port 8082 was already in use的问题,并通过介绍端口的使用原理和操作系统的端口管理机制,可以更有效地解决端口冲突问题,并确保Web服务器能够顺利启动和运行。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
存储 负载均衡 并行计算
实现优雅并行编程:确保正确性与提升性能的关键要素
在程序开发中,并行编程一种利用多个处理器或计算资源同时执行多个任务的编程方式,它能够提高计算效率和性能,是提高计算效率和性能的关键手段,但它也带来了一系列复杂的问题,涉及到任务分解、数据同步、资源分配等诸多复杂问题,稍有不慎就可能导致性能瓶颈、死锁甚至数据不一致等状况。编写优雅的并行程序需要在保证程序正确性的前提下,实现高效的并行计算。那么本文就来探讨一下如何在保证程序正确性的前提下,实现优雅的并行程序,以提升计算效率和性能,包括任务分解、数据同步和资源分配等方面的关键要素,希望能够为读者提供一些有用的指导和启示。
311 2
实现优雅并行编程:确保正确性与提升性能的关键要素
|
缓存 前端开发 JavaScript
JavaScript进阶 - Web Workers与Service Worker
【7月更文挑战第10天】在Web开发中,Web Workers和Service Worker提升性能。Workers运行后台任务,防止界面冻结。Web Workers处理计算密集型任务,Service Worker则缓存资源实现离线支持。常见问题包括通信故障、资源限制、注册错误及缓存更新。通过示例代码展示了两者用法,并强调生命周期管理和错误处理的重要性。善用这些技术,可构建高性能的Web应用。
324 0
|
canal 关系型数据库 MySQL
"揭秘阿里数据同步黑科技Canal:从原理到实战,手把手教你玩转MySQL数据秒级同步,让你的数据处理能力瞬间飙升,成为技术界的新晋网红!"
【8月更文挑战第18天】Canal是一款由阿里巴巴开源的高性能数据同步系统,它通过解析MySQL的增量日志(Binlog),提供低延迟、可靠的数据订阅和消费功能。Canal模拟MySQL Slave与Master间的交互协议来接收并解析Binary Log,支持数据的增量同步。配置简单直观,包括Server和Instance两层配置。在实战中,Canal可用于数据库镜像、实时备份等多种场景,通过集成Canal Client可实现数据的消费和处理,如更新缓存或写入消息队列。
1635 0
|
JavaScript 前端开发 Docker
全栈开发实战:结合Python、Vue和Docker进行部署
【4月更文挑战第10天】本文介绍了如何使用Python、Vue.js和Docker进行全栈开发和部署。Python搭配Flask创建后端API,Vue.js构建前端界面,Docker负责应用的容器化部署。通过编写Dockerfile,将Python应用构建成Docker镜像并运行,前端部分使用Vue CLI创建项目并与后端交互。最后,通过Nginx和另一个Dockerfile部署前端应用。这种组合提升了开发效率,保证了应用的可维护性和扩展性,适合不同规模的企业使用。
792 4