DataBinding源码浅析---初始化过程

作为Google官方发布的支持库,DataBinding实现了UI组件和数据源的双向绑定,同时在Jetpack组件中,也将DataBinding放在了Architecture类型之中。对于DataBinding的基础使用请先翻阅前两篇文章的详细阐述。本文所用代码也是建立在之前工程基础之上。

初始化分析

按照官方文档所说,Databinding在编译期会生成代码,利用的技术是Apt(annotation-processing-tool)。在运行完工程后,可以看到build文件夹下生成多个文件夹和文件,看到了这里,就可以明白其核心原理肯定跟注解处理器有关系,其实所有通过APT生成代码的框架(比如ButterKnife,dagger2,hit等),大多数情况下其核心逻辑的实现都在生成代码中,可以说其完全就是通过注解处理器产生的,因此需要我们重点翻阅的都是生成的代码。在我们按照规则写完布局文件后,会生成相应的.java文件,文件名为xml文件名加上Binding后缀。原工程则生成是的ActivityMainBinding.java文件,这点不难理解。

从XML开始

让我们关注build目录下的intermediates目录,你会发现,相较于其他没有使用Data Binding的工程,这里多了几个目录:

image.gif
不难猜出,这是DataBinding特有的目录风格。我们看到最后一个文件夹,展开会发现:

image.gif
这里的activity_main-layout.xml像极了我们activity所使用布局。点开会发现里面充满了各种标签。(如果一开始里面代码只有一行,则可以使用快捷键 Windows : ctrl+Alt + L调整代码格式)

image.gif

先列出原布局文件:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"xmlns:app="http://schemas.android.com/apk/res-auto"><data><import type="com.example.dbjavatest.bean.DataBean"/><variablename="dataInfoBean"type="DataBean" /></data><androidx.constraintlayout.widget.ConstraintLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><TextViewandroid:id="@+id/tv_data"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="26sp"android:textColor="@color/purple_200"android:text="@{dataInfoBean.dataInfo}"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"android:layout_marginLeft="50dp"/><EditTextandroid:layout_width="match_parent"android:layout_height="wrap_content"android:hint="请输入数据"android:text="@={dataInfoBean.dataInfo}"app:layout_constraintTop_toBottomOf="@+id/tv_data"android:textSize="25sp"android:layout_marginTop="30dp"android:paddingLeft="20dp"/></androidx.constraintlayout.widget.ConstraintLayout>
</layout>

可以看出这里面总共三个控件,对应activity_main-layout.xml中有三个< target>节点。

image.png
节点里view属性名称则刚好可以是我们布局中所用控件,这里就是我们在布局中声明的控件无疑。在这些< target>信息中,还可看到所赋予的tag信息(binding_1、binding_2)。而在Expression标签中,text对应属性值里有“dataInfoBean.dataInfo”这就刚好对应上数据来源。当然,仅仅靠这个文本,是不可能生成一个能绘制出来的效果。这时还要观察另外一个文件。

在intermediates/incremental目录下,相应的有效文件夹为mergeDebugResources\stripped.dir\layout 下,对应的文件名即为布局文件名:
image.gif
点开后你会发现,相较于原始的activity_main.xml布局文件,< layout>和< data>标签都消失了:

image.png
且内部控件都多了一个属性,android:tag属性。此tag属性所赋id则跟build/intermediates/data_binding_layout_info_type_package/debug/out/activity_main-layout.xml中的标签里的tag相对应。不难猜出,其xml具体显示流程与这俩文件紧密相关。

接下来就要去看整体的流程了。

初始化流程

要分析整体流程还得从MainActivity入手,DataBindingUtil.setContentView(this, R.layout.activity_main);就是完成XML布局的初始化操作:

image.png
点进去查看其源码:

image.gif

image.gif
可以发现这里通过获取Window的decorView,来把传进来的layoutId(即我们的布局)通过bindToAddedViews()绑定到屏幕视图上。这里的contentView和其id.content是工程创建时Activity就自带的默认FrameLayout,对这个不了解的要去了解下屏幕渲染机制,在这里不需要纠结。

继续观察bindToAddedViews()内部对于绑定的过程实现:

image.gif
可看到最终都是调用的bind():

image.gif
这其中有个变量,sMapper。我们看到声明地方:

image.gif
可以看到此变量是由一个生成类new出来,且此类并不是原先就存在,只有在编译过程结束后才生成出来的文件:

image.gif
而在此类中最重要的就是getDataBinder(),在此方法中,可以看到拿标签流程:

image.png
通过判断是activity_main.xml的id来返回一个new ActivityMainBindingImpl(component, view);对象。我们点进去观察此对象源码:

源码图片1.png

可以看出,对应取控件id等操作来源得看mapBindings内部实现:

源码图片2.png
源码图片3.png
此方法后续逻辑基本上都是如此,在这方法体内将所有view存进一个数组,然后在ActivityMainBindingImpl中通过bindings[1]去获取view实例:
源码图片4.png
然后通过invalidateAll()更新所有UI。

以上不难看出这些流程就是XML布局的初始化所有流程。在初始化结束后,xml的控件信息就存在了DataBinding对象里,就可以通过DataBinding对象拿到具体对应控件对象实例了。

ActivityMainBinding viewDataBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
viewDataBinding.tvData.setText("拿到对象实例了");

这也正是为什么DataBinding可以不用findViewById了的原因。其实不难想到,随着页面的UI复杂度的增加,dataBinding对内存的消耗也会越大,个人感觉这是DataBinding的缺点。(后面有时间,我会去对比DataBinding与常规架构所构建的APP在内存和整体性能上的区别)

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

《乱弹篇(十四)香火旺》

连日来&#xff0c;“大年初一烧香祈福&#xff0c;北京雍和宫人山人海”这一词条登上社交网站热搜&#xff0c;对这一现象的描述多为“初一凌晨 民众在雍和宫前排大队”&#xff0c;“大年初一&#xff0c;雍和宫内人山人海&#xff0c;烟雾缭绕”&#xff0c;“雍和宫迎来6万…

全栈笔记_工具篇(nvm免安装版配置)

免安装版配置 下载nvm包:选择免安装压缩包nvm-noinstall.zip 解压zip包:将压缩包解压到指定目录,如:C:\nvm 新增环境变量: NVM_HOME:nvm解压之后的文件路径,对应配置文件里的root值NVM_SYMLINK:nvm 文件夹里新建 nodejs文件夹,对应配置文件里的path值 修改环境变量Pat…

[leetcode] 33. 搜索旋转排序数组

文章目录 题目描述解题方法二分查找java代码复杂度分析 题目描述 整数数组 nums 按升序排列&#xff0c;数组中的值 互不相同 。 在传递给函数之前&#xff0c;nums 在预先未知的某个下标 k&#xff08;0 < k < nums.length&#xff09;上进行了 旋转&#xff0c;使数组…

AJAX——常用请求方法

1 请求方法 请求方法&#xff1a;对服务器资源&#xff0c;要执行的操作 2 数据提交 场景&#xff1a;当数据需要在服务器上保存 3 axios请求配置 url&#xff1a;请求的URL网址 method&#xff1a;请求的方法&#xff0c;GET可以省略&#xff08;不区分大小写&#xff09; …

【数据结构】13:表达式转换(中缀表达式转成后缀表达式)

思想&#xff1a; 从头到尾依次读取中缀表达式里的每个对象&#xff0c;对不同对象按照不同的情况处理。 如果遇到空格&#xff0c;跳过如果遇到运算数字&#xff0c;直接输出如果遇到左括号&#xff0c;压栈如果遇到右括号&#xff0c;表示括号里的中缀表达式已经扫描完毕&a…

协议-TCP协议-基础概念04-可能发生丢包的位置-linux配置项梳理(TCP连接的建立和断开、收发包过程)

可能发生丢包的位置-linux配置项梳理&#xff08;TCP连接的建立和断开、收发包过程&#xff09;-SYN Flood攻击和防御原理 参考来源&#xff1a; 极客时间-Linux性能优化实战 极客时间-Linux内核技术实战课 到底是哪里发生了丢包呢&#xff1f; Linux 的网络收发流程 从图中…

CentOS7下如何安装Nginx

一、Ngxin是什么 Nginx是一个开源的 Web 服务器&#xff0c;具有反向代理、负载均衡、缓存等功能。它可以作为 HTTP 服务器&#xff0c;将服务器上的静态文件&#xff08;如 HTML、图片&#xff09;通过 HTTP 协议展现给客户端&#xff0c;也可以实现动静分离&#xff0c;把动态…

PgSQL内核特性 - push-based pipeline 执行引擎

PgSQL内核特性 - push-based pipeline 执行引擎 数据库的SQL执行引擎负责处理和执行SQL请求。通常情况下&#xff0c;查询优化器会输出物理执行计划&#xff0c;一般由一系列的算子组成。当前&#xff0c;有两种算子流水线构建方式&#xff1a;1&#xff09;需求驱动的流水线&a…

【大厂AI课学习笔记】【1.6 人工智能基础知识】(4)深度学习和机器学习

关于深度学习和机器学习&#xff0c;出来包含关系之外&#xff0c;还有如上总结的知识点。 分别从特征处理、学习方法、数据依赖、硬件依赖等4个方面&#xff0c;进行了总结。 从特征处理上看&#xff1a;深度学习从数据中习得高级特征&#xff0c;并自行创建新的特征。这比普…

python入门篇11-面向对象的基础使用

全文目录,一步到位 1.前言简介1.1 专栏传送门1.1.1 上文小总结1.1.2 上文传送门 2. python基础使用2.1 面向对象的基础使用2.1.1 创建类2.1.2 使用对象(定义成员变量)2.1.3 成员方法的定义与使用2.1.4 构造方法的使用2.1.5 常用魔术方法 2.2 面向对象思想核心2.2.1 面向对象_私…

立体视觉几何 (三)

立体视觉系统概述 误差分析 考虑对应于深度 Z 的视差 d 的匹配对。我们想要评估 ΔZ&#xff0c;即视差误差引起的深度误差。将 Z 对 d 求导&#xff0c;得到&#xff1a; 立体视觉中基线&#xff08;baseline&#xff09;、焦距&#xff08;focal length&#xff09;和立体重…

游泳时可以听歌的耳机有哪些?戴游泳耳机有哪些好处?

游泳和跑步在某种程度上相似&#xff0c;特别是在短距离冲刺时&#xff0c;大脑似乎变得空白&#xff0c;而在中长距离的有氧运动中&#xff0c;身体感到疲劳&#xff0c;但大脑却异常清晰&#xff0c;时间却显得格外漫长。如何打发时间&#xff0c;让游泳锻炼变得不无聊&#…

中国电子学会2020年12月份青少年软件编程Scratch图形化等级考试试卷三级真题(编程题)

编程题(共3题&#xff0c;共30分) 36.绘制图形 1. 准备工作: &#xff08;1&#xff09;保留默认小猫角色&#xff0c;隐藏角色&#xff1b; &#xff08;2&#xff09;背景为白色背景。 2. 功能实现: &#xff08;1&#xff09;绘制如下图所示的图案&#xff1b; &…

点云标注工具

目录 3d手势识别 c 3d关键点&#xff0c;Bounding Box Labels Rectangle Labels KITTI 3D Ground Truth Annotator c标注工具 3d手势识别 GitHub - 99xtaewoo/Automated-Hand-3D-pose-annotation-Tool: Automated Hand 3D pose annotation Tool c 3d关键点&#xff0c;Bou…

【办公类-23-02】20240212徐迟《江南小镇(南浔古镇)》“水晶晶”和景物”数量提取66个

作品展示 背景需求&#xff1a; 2024年春节前夕&#xff0c;我与家人前往浙江湖州、南浔旅行。探寻母亲、外婆外公、曾外婆的祖籍南浔的风土人情。在古镇上看到了”著名诗人“徐迟”的介绍。 母亲说&#xff1a;我的姑母就是在南浔读了小学和中学&#xff0c;她小学时的老师就…

机器学习系列——(十三)多项式回归

引言 在机器学习领域&#xff0c;线性回归是一种常见且简单的模型。然而&#xff0c;在某些情况下&#xff0c;变量之间的关系并不是线性的&#xff0c;这时候我们就需要使用多项式回归来建模非线性关系。多项式回归通过引入高次项来扩展线性回归模型&#xff0c;从而更好地拟…

Github 2024-02-12 开源项目日报 Top10

根据Github Trendings的统计&#xff0c;今日(2024-02-12统计)共有10个项目上榜。根据开发语言中项目的数量&#xff0c;汇总情况如下&#xff1a; 开发语言项目数量Rust项目3Python项目3JavaScript项目1TypeScript项目1C项目1C项目1PowerShell项目1非开发语言项目1 SubQuery…

Elasticsearch:使用查询规则(query rules)进行搜索

在之前的文章 “Elasticsearch 8.10 中引入查询规则 - query rules”&#xff0c;我们详述了如何使用 query rules 来进行搜索。这个交互式笔记本将向你介绍如何使用官方 Elasticsearch Python 客户端来使用查询规则。 你将使用 query rules API 将查询规则存储在 Elasticsearc…

docker之centos7容器常用命令和服务安装

一、前言 以前我们如果想在windows环境下使用linux系统&#xff0c;最早的是一台主机上安装双机系统&#xff0c;再后来我们有了VMware&#xff0c;可以通过workstations虚拟化平台安装虚拟机。现在我们还可以通过docker安装linux容器&#xff0c;容器更轻量也更便捷。不过凡事…

工业级加固平板丨亿道三防平板电脑丨安卓工业平板丨改善车队管理

在现代物流和运输行业中&#xff0c;车队管理是一个复杂而重要的任务。为了更好地管理车队&#xff0c;提高工作效率和减少成本&#xff0c;许多企业正在采用新技术和工具。其中&#xff0c;三防平板电脑作为一种功能强大且适应恶劣环境的设备&#xff0c;已经在车队管理中得到…