从源码的角度说说Activity的setContentView的原理(二)

前文http://blog.csdn.net/sahadev_/article/details/49072045虽然讲解了LayoutInflate的整个过程,但是其中很多地方是不准确不充分的,这一节就详细讲一下我们上一节遗留的细节问题,我们遗留的问题有这些:

1.在PhoneWindow的setContentView里我们看到了一个mLayoutInflater对象,我们还没清楚它从哪来?

2.mLayoutInflater对象后来所调用的那些方法有没有被重载?

3.mFactory,mFactory2, mPrivateFactory这三个对象是否不为空?如果系统默认给它设置了值,那么后来生成的View是不是就是通过它们来设置的呢?

好,接下来就让我们一起把这些问题解开:


1. 我们先来看看mLayoutInflater从哪来,我们推测它极有可能和我们一样是使用这样的方式得来的:

LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);

但,这仅仅是推测,我们要看到实际的代码:

    public PhoneWindow(Context context) {super(context);mLayoutInflater = LayoutInflater.from(context);}

通过查看源码我们可以得知,在 PhoneWindow的构造方法里是LayoutInflater.from(context);的方式对mLayoutInflater对象进行了初始化,看来,它也是和我们一样使用了同一个系统提供的LayoutInflater对象,那么,系统提供的这个LayoutInflater对象是在哪被构造和添加进去的呢?这我们就需要去Context.getSystemService方法里一探究竟了:

我们知道getSystemService其实调用的就是ContextImpl的方法,ContextImpl是Context的具体实现类,我们进入ContextImpl的getSystemService中一探究竟:

    public Object getSystemService(String name) {ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);return fetcher == null ? null : fetcher.getService(this);}

好,看来所有的服务都是通过SYSTEM_SERVICE_MAP取出来的,那么我们看看这些服务什么时候被添加进去的,在 ContextImpl这个类中我们看到有个静态方法

    private static void registerService(String serviceName, ServiceFetcher fetcher) {if (!(fetcher instanceof StaticServiceFetcher)) {fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++;}SYSTEM_SERVICE_MAP.put(serviceName, fetcher);}

看来所有的服务都是通过它加进去的,那什么时候加进去的呢,我们在这个类当中可以看到一段很长的静态代码块,在代码块中发现了它的身影:

    static {...registerService(LAYOUT_INFLATER_SERVICE, new ServiceFetcher() {public Object createService(ContextImpl ctx) {return PolicyManager.makeNewLayoutInflater(ctx.getOuterContext());}});...}

好吧,看来系统系统的 LayoutInflater的对象其实是由PolicyManager.makeNewLayoutInflater(ctx.getOuterContext());这个方法构造出来的(又是PolicyManager,我们刚才看到它执行的makeNewWindow,看来它做了不少事情), 不用多说,我们直接进入Policy中看(不清楚这个过程的同学可以直接看这里 http://blog.csdn.net/sahadev_/article/details/49072045 ):

    public LayoutInflater makeNewLayoutInflater(Context context) {return new PhoneLayoutInflater(context);}
噢,原来所有的工作都是它在干啊!到这里,我们第一个问题就清楚了。


2.mLayoutInflater对象后来所调用的那些方法有没有被重载?其实这个问题我们直接进PhoneLayoutInflater中就可以知道答案:

    /** Override onCreateView to instantiate names that correspond to thewidgets known to the Widget factory. If we don't find a match,call through to our super class.*/@Override protected View onCreateView(String name, AttributeSet attrs) throws ClassNotFoundException {for (String prefix : sClassPrefixList) {try {View view = createView(name, prefix, attrs);if (view != null) {return view;}} catch (ClassNotFoundException e) {// In this case we want to let the base class take a crack// at it.}}return super.onCreateView(name, attrs);}

噢,原来我们在上一篇文章当中分析的onCreateView方法是没有被调用的,那看来父类中的这个方法的功能是不满足的,那我们分析分析被复写的这个方法:

我们可以看到这个方法内部在遍历一个字符串数组,这个字符串数组被定义在类里:

    private static final String[] sClassPrefixList = {"android.widget.","android.webkit.","android.app."};

在上一篇文章当中,我请大家在onCreateView中注意调用createView方法的第二个参数是"android.view.",这里被重写,看来是不满足了,子类实现了更为强大的功能,支持了更多的包进行加载,它这个过程一直在尝试去创建View,直到成功。好,我们第二个问题也解决完了。


3.mFactory,mFactory2, mPrivateFactory这三个对象是否不为空?看来这个问题我们就都知道了,PhoneLayoutInflater在构造的时候调用的是:

    public PhoneLayoutInflater(Context context) {super(context);}

后来也没有对它进行什么设置,所以看来它们都是空,这里这3个对象是开放给我们使用的,我们可以在View被加载的时候动态的修改它们的效果,这是个很强大的功能,比如动态修改皮肤什么的,希望你们可以手动去实现一下,☺,谢谢。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/479545.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

美团智能配送系统的运筹优化实战

深入各个产业已经成为互联网目前的主攻方向,线上和线下存在大量复杂的业务约束和多种多样的决策变量,为运筹优化技术提供了用武之地。作为美团智能配送系统最核心的技术之一,运筹优化是如何在美团各种业务场景中进行落地的呢?本文…

Android如何给无法更改继承关系的Activity更换ActionBar(setContentView方法实战)

前言: 通常我们有时候会直接使用ADT工具直接新建一个Activity页,而这个Activity我们又无法更改它的父类,那遇到这种情况该如何处理呢?其实很简单,好,看如何来解决这个问题: 先来看看这个问题出…

论文浅尝 | 基于属性embeddings的跨图谱实体对齐

论文笔记整理:谭亦鸣,东南大学博士生,研究方向为知识库问答。来源:AAAI 2019链接:https://aaai.org/ojs/index.php/AAAI/article/view/3798跨图谱实体对齐任务的目标是从两个不同知识图谱中找出同一 real-world 实体&a…

LeetCode 771. 宝石与石头(哈希)

文章目录1. 题目信息2. 解题1. 题目信息 给定字符串J 代表石头中宝石的类型,和字符串 S代表你拥有的石头。 S 中每个字符代表了一种你拥有的石头的类型,你想知道你拥有的石头中有多少是宝石。 J 中的字母不重复,J 和 S中的所有字符都是字母…

开启NLP新时代的BERT模型,真的好上手吗?

都说BERT模型开启了NLP的新时代,更有“BERT在手,天下我有”的传说,它解决了很多NLP的难题:1、BERT让低成本地训练超大规模语料成为可能;2、BERT能够联合神经网络所有层中的上下文来进行训练,实现更精准的文…

YOLO系列:YOLOv1,YOLOv2,YOLOv3,YOLOv4,YOLOv5简介

原文链接: https://zhuanlan.zhihu.com/p/136382095 YOLO系列:YOLOv1,YOLOv2,YOLOv3,YOLOv4,YOLOv5简介YOLO系列是基于深度学习的回归方法。RCNN, Fast-RCNN,Faster-RCNN是基于深度学习的分类方法。YOLO官网:https://g…

一站式机器学习平台建设实践

本文根据美团配送资深技术专家郑艳伟在2019 SACC(中国系统架构师大会)上的演讲内容整理而成,主要介绍了美团配送技术团队在建设一站式机器学习平台过程中的经验总结和探索,希望对从事此领域的同学有所帮助。 0. 写在前面 AI是目前…

(Android开发辅助工具)动态广播注册解注工具

平常我们开发的时候需要使用到动态注册广播,如果在一个类内注册很多的广播代码就会既冗余又乱糟糟的,就像这样: msgReceiver new NewMessageBroadcastReceiver();IntentFilter intentFilter new IntentFilter(EMChatManager.getInstance().…

LeetCode 535. TinyURL 的加密与解密(哈希)

文章目录1. 题目信息2. 哈希解题1. 题目信息 TinyURL是一种URL简化服务, 比如:当你输入一个URL https://leetcode.com/problems/design-tinyurl 时,它将返回一个简化的URL http://tinyurl.com/4e9iAk. 要求:设计一个 TinyURL 的…

论文浅尝 | Doc2EDAG:一种针对中文金融事件抽取的端到端文档级框架

论文笔记整理:叶宏彬,浙江大学博士生,研究方向为知识图谱、自然语言处理。链接:https://arxiv.org/pdf/1904.07535.pdf背景大多数现有的事件提取(EE)方法仅提取句子范围内的事件参数。但是,此类…

NeurIPS'20 | 通过文本压缩,让BERT支持长文本

作者 | wangThr来源 | 知乎这是今年清华大学及阿里巴巴发表在NIPS 2020上的一篇论文《CogLTX: Applying BERT to Long Texts》,介绍了如何优雅地使用bert处理长文本。作者同时开源了不同NLP任务下使用COGLTX的代码:论文题目:CogLTX: Applying…

福利!Android官方网站出现中文版本!

这两天在Android开发者网站上查东西的时候发现有中文的搜索结果,点开结果全是中文的,以后可以畅通无阻的看文档了,快来围观。

自然场景人脸检测技术实践

一、 背景 人脸检测技术是通过人工智能分析的方法自动返回图片中的人脸坐标位置和尺寸大小,是人脸智能分析应用的核心组成部分,具有广泛的学术研究价值和业务应用价值,比如人脸识别、人脸属性分析(年龄估计、性别识别、颜值打分和…

LeetCode 257. 二叉树的所有路径(DFS)

文章目录1. 题目2. DFS解题1. 题目 给定一个二叉树,返回所有从根节点到叶子节点的路径。 说明: 叶子节点是指没有子节点的节点。 示例:输入:1/ \ 2 3\5输出: ["1->2->5", "1->3"]解释: 所有根节点到叶子节点的路径为: 1->…

JAVA BIO

JAVA BIO深入剖析1. Java BIO 基本介绍2. Java BIO 工作机制3. 传统BIO编程4. BIO模式下的多发和多收消息5. BIO模式下接收多个客户端6. 伪异步I/O编程7. 基于BIO的文件上传8. Java BIO模式下的端口转发9. 基于BIO模式下的即时通信功能清单简单说明项目启动与演示1. Java BIO 基…

速览EMNLP 2020上录取的知识图谱相关论文

文 | 泽宇源 | 知乎前不久,自然语言处理领域三大顶会之一的 EMNLP 2020 发布了论文录取的结果。在EMNLP 2020论文正式出版之前,泽宇搜集了目前Arxiv上已经发布出来的录取在EMNLP 2020上所有和知识图谱相关的论文,下面我们就一起来一睹为快。1…

技术动态 | 数据库研究者视角下的知识图谱研究

本文转载自公众号:图谱学苑 。本次讲解的是数据库领域的三大会(SIGMOD、VLDB、ICDE)近两年关于图数据的研究进展,特别是知识图谱的最新研究。知识图谱是2012年Google为改进其搜索引擎而提出的概念,其本质是一个描述事物…

MultiDex

原文转自:http://coolpers.github.io/multidex/2015/04/13/multidex.html 1.MultiDex的产生背景 当Android系统安装一个应用的时候,有一步是对Dex进行优化,这个过程有一个专门的工具来处理,叫DexOpt。DexOpt的执行过程是在第一次加…

PYTHON得到pdf页数、遍历当前文件夹

#第一步安装PyPDF2 pip install PyPDF2#第二步导入相应的模块 from PyPDF2 import PdfFileReader#第三步:定义相对应的函数 def get_num_pages(file_path):"""获取文件总页码:param file_path: 文件路径:return:"""reader PdfFileRe…

LeetCode 814. 二叉树剪枝(递归)

文章目录1. 题目2. 递归解题1. 题目 给定二叉树根结点 root ,此外树的每个结点的值要么是 0,要么是 1。 返回移除了所有不包含 1 的子树的原二叉树。 把只包含0的子树删除(断开) 来源:力扣(LeetCode&…