美文网首页
Android-DataBinding-原理-编译期

Android-DataBinding-原理-编译期

作者: CodeMagic | 来源:发表于2020-02-13 12:21 被阅读0次

概述

  • DataBinding框架分为两部分:编译期和运行时;编译期根据XML中声明式的绑定表达式以及一系列注解自动生成代码ViewDataBinding类;运行时通过特定方法(notifyPropertyChanged)对某些绑定表达式标记脏数据,下一帧根据dirtyFlag对View进行更新;
  • 编译期原理主要根据编译产物或者中间产物,进行反推;运行期原理根据源码分析;
  • 编译期比较复杂,所以只是结合网上相关资料和编译产物进行反推,大概了解编译期做了哪些工作;

网上相关资料

  • 之前在网上看到过一篇讲述编译期的简单介绍(https://www.jianshu.com/p/eb29c691d370
    ),这里做个大概描述,后面会根据DataBinding最新版本的编译产物进行一些验证;
  • ANDROID_DataBinding_Compiler.png
  • 白色部分为输入;黄色部分为编译器处理类;蓝色部分为中间产物;绿色部分为最终产物;
    • 白色
      • res/layout和代码中的注解;
    • 黄色
      • aapt编译时处理:MakeCopy.java;
      • gradle-api处理:DataBinderPlugin.java;
      • AbstractProcessor处理:ProcessDataBinding.java;
    • 蓝色
      • data-binding-info文件夹:包含layout中的变量,绑定表达式相关信息;
      • setter_store.bin:包含所有setter相关信息;
      • layoutinfo.bin:包含所有layout相关信息;br.bin:包含所有BR相关信息;
    • 绿色
      • data-binding-layout-out:保存layout中view相关信息;
      • DataBindingInfo.class:一个看似空的类,但在SOURCE阶段包含了一个@BindingBuildInfo注解,包含了基本DataBinding的基本信息;
      • DataBindingComponent.class:会根据自定义的DataBindingComponent自动生成对应实例化方法;
      • ViewDataBinding.class的子类;
      • BR.class;
      • DataBindingMapper.class:用于寻找某个layout.xml对应的ViewDataBinding类;
  • 流程
    • 资源处理
      • aapt/gradle-api阶段,都会触发资源处理,DataBinding都会扫描一遍现有的资源,生成不包含<layout>的data-binding-layout-out以及DataBinding所需要的data-binding-info;
    • 生成DataBindingInfo.class
      • 资源处理后,aapt/gradle-api都会去生成DataBindingInfo.class,把相关的信息写入DataBindingInfo.class的@BindingBuildInfo注解中;
    • 监听到注解变化
      • 生成@BindingBuildInfo注解,或者code中发现有新的注解写入,AbstractProcessor注解处理器就开始执行注解处理;DataBinding中有一个ProcessDataBinding.java类专门来处理DataBinding相关的注解;
    • ProcessDataBinding处理注解,生成bin
      • ProcessDataBinding中处理注解永远会按顺执行3步,ProcessMethodAdapter,ProcessExpressions,ProcessBindable。每次执行都会从磁盘反序列化对应的bin文件,然后往bin中写入新的,完成后再序列化到磁盘;
    • 生成最终产物
      • 执行ProcessMethodAdapter生成DataBindingComponents.class;执行ProcessExpressions生成ViewDataBinding.class子类(ActivityDetail2Binding.class),并触发DataBindingMapper.class更新;执行ProcessBindable生成BR.class,并触发DataBindingMapper.class更新;

验证

  • gradle版本使用的是 com.android.tools.build:gradle:3.5.3
  • 中间产物
    • ./build/intermediates/data-binding/debug/bundle-bin目录
      • 包含两个文件:module-br.bin和module-setter_store.json;
      • 第一个文件应该是用来生成该module对应的br文件;第二个文件记录了该module中所有绑定注解的相关信息(比如,BindingAdapter关联的属性名,View类型,参数类型,以及该方法所属的类);
    • ./build/intermediates/data_binding_dependency_artifacts/debug/dataBindingMergeDependencyArtifactsDebug/out目录
      • 包含两类文件module-br.bin和module-setter_store.json;文件内容同上;
    • ./build/intermediates/data_binding_base_class_log_artifact/debug/dataBindingGenBaseClassesDebug/out目录
      • 包含一个文件module-binding_classes.json;包含从XML名称到ViewDataBinding类的映射关系(包括XML中变量类型);
    • ./build/intermediates/data_binding_base_class_log_dependency_artifacts/debug/out目录
      • 包含依赖module,依赖库的binding_class.json文件,文件内容同上;
    • ./build/intermediates/data_binding_layout_info_type_merge/debug/mergeDebugResources/out目录
      • 包含了XML中变量部分以及绑定表达式信息,不包含View信息;
  • 最终产物
    • BR文件
      • 包含变量名和属性名(@Bindable注解过的getter方法)对应的ID;
    • Binding/BindingImp文件
      • XML文件对应的绑定类,实现了运行时自动更新UI的逻辑;
    • DataBindingComponent文件
      • 如果BindingAdapter注解在实例方法上,会在该接口中生成获取该实例的接口方法;
    • DataBinderMapperImpl文件
      • 包含了layout对应的id到Binding类的映射,XML的rootView的tag到layout的id的映射,BR中的id到属性名的映射;

总结

  • 网上资料和验证结合来看,整体流程没什么变化,除了一些细小的差别(比如Binding类又多了BindingImp子类);
  • 流程
    • 开发阶段:主要涉及两部分,XML(layout和data标签)和注解;
    • 资源处理:将XML拆分成两部分:一部分为layout文件,最终打包到apk中的layout文件,和传统写法差不多,唯一不一样的就是相关View的Tag会改成binding格式,这个是编译期和运行时的纽带;另外一部分是layout-info文件,包括变量和绑定表达式相关信息;
    • 注解处理:先处理绑定注解(除Bindable)生成setter_store.json文件;再根据layout-info文件和setter_store.json文件处理绑定表达式,生成Binding/DataBindingComponent文件;再处理Bindable注解,生成BR文件;再生成BindingImp文件(这个是个人猜测,因为BindingImp的逻辑是要根据BR值生成dirtyFlag);再生成DataBinderMapperImpl文件;

存疑

  • DataBindingInfo文件及BindingBuildInfo注解有什么用?
  • DataBindingComponent不建议使用,在实例方法上注解BindingAdapter,还不如直接在对应的Activity中对可观察数据源挂监听做特殊逻辑;

相关文章

网友评论

      本文标题:Android-DataBinding-原理-编译期

      本文链接:https://www.haomeiwen.com/subject/xmfcfhtx.html