概述
- DataBinding框架分為兩部分:編譯期和運(yùn)行時(shí);編譯期根據(jù)XML中聲明式的綁定表達(dá)式以及一系列注解自動(dòng)生成代碼ViewDataBinding類;運(yùn)行時(shí)通過(guò)特定方法(notifyPropertyChanged)對(duì)某些綁定表達(dá)式標(biāo)記臟數(shù)據(jù),下一幀根據(jù)dirtyFlag對(duì)View進(jìn)行更新;
- 編譯期原理主要根據(jù)編譯產(chǎn)物或者中間產(chǎn)物其做,進(jìn)行反推冷守;運(yùn)行期原理根據(jù)源碼分析茂嗓;
- 編譯期比較復(fù)雜尘惧,所以只是結(jié)合網(wǎng)上相關(guān)資料和編譯產(chǎn)物進(jìn)行反推惭适,大概了解編譯期做了哪些工作笙瑟;
網(wǎng)上相關(guān)資料
- 之前在網(wǎng)上看到過(guò)一篇講述編譯期的簡(jiǎn)單介紹(http://www.reibang.com/p/eb29c691d370
),這里做個(gè)大概描述癞志,后面會(huì)根據(jù)DataBinding最新版本的編譯產(chǎn)物進(jìn)行一些驗(yàn)證往枷; - ANDROID_DataBinding_Compiler.png
- 白色部分為輸入;黃色部分為編譯器處理類凄杯;藍(lán)色部分為中間產(chǎn)物错洁;綠色部分為最終產(chǎn)物;
- 白色
- res/layout和代碼中的注解戒突;
- 黃色
- aapt編譯時(shí)處理:MakeCopy.java屯碴;
- gradle-api處理:DataBinderPlugin.java;
- AbstractProcessor處理:ProcessDataBinding.java膊存;
- 藍(lán)色
- data-binding-info文件夾:包含layout中的變量导而,綁定表達(dá)式相關(guān)信息忱叭;
- setter_store.bin:包含所有setter相關(guān)信息;
- layoutinfo.bin:包含所有l(wèi)ayout相關(guān)信息今艺;br.bin:包含所有BR相關(guān)信息韵丑;
- 綠色
- data-binding-layout-out:保存layout中view相關(guān)信息;
- DataBindingInfo.class:一個(gè)看似空的類虚缎,但在SOURCE階段包含了一個(gè)@BindingBuildInfo注解撵彻,包含了基本DataBinding的基本信息;
- DataBindingComponent.class:會(huì)根據(jù)自定義的DataBindingComponent自動(dòng)生成對(duì)應(yīng)實(shí)例化方法遥巴;
- ViewDataBinding.class的子類千康;
- BR.class;
- DataBindingMapper.class:用于尋找某個(gè)layout.xml對(duì)應(yīng)的ViewDataBinding類铲掐;
- 白色
- 流程
- 資源處理
- aapt/gradle-api階段拾弃,都會(huì)觸發(fā)資源處理,DataBinding都會(huì)掃描一遍現(xiàn)有的資源摆霉,生成不包含<layout>的data-binding-layout-out以及DataBinding所需要的data-binding-info豪椿;
- 生成DataBindingInfo.class
- 資源處理后,aapt/gradle-api都會(huì)去生成DataBindingInfo.class携栋,把相關(guān)的信息寫入DataBindingInfo.class的@BindingBuildInfo注解中搭盾;
- 監(jiān)聽到注解變化
- 生成@BindingBuildInfo注解,或者code中發(fā)現(xiàn)有新的注解寫入婉支,AbstractProcessor注解處理器就開始執(zhí)行注解處理鸯隅;DataBinding中有一個(gè)ProcessDataBinding.java類專門來(lái)處理DataBinding相關(guān)的注解;
- ProcessDataBinding處理注解向挖,生成bin
- ProcessDataBinding中處理注解永遠(yuǎn)會(huì)按順執(zhí)行3步蝌以,ProcessMethodAdapter,ProcessExpressions何之,ProcessBindable跟畅。每次執(zhí)行都會(huì)從磁盤反序列化對(duì)應(yīng)的bin文件,然后往bin中寫入新的溶推,完成后再序列化到磁盤徊件;
- 生成最終產(chǎn)物
- 執(zhí)行ProcessMethodAdapter生成DataBindingComponents.class;執(zhí)行ProcessExpressions生成ViewDataBinding.class子類(ActivityDetail2Binding.class)蒜危,并觸發(fā)DataBindingMapper.class更新虱痕;執(zhí)行ProcessBindable生成BR.class,并觸發(fā)DataBindingMapper.class更新辐赞;
- 資源處理
驗(yàn)證
- gradle版本使用的是
com.android.tools.build:gradle:3.5.3
部翘; - 中間產(chǎn)物
- ./build/intermediates/data-binding/debug/bundle-bin目錄
- 包含兩個(gè)文件:module-br.bin和module-setter_store.json;
- 第一個(gè)文件應(yīng)該是用來(lái)生成該module對(duì)應(yīng)的br文件占拍;第二個(gè)文件記錄了該module中所有綁定注解的相關(guān)信息(比如略就,BindingAdapter關(guān)聯(lián)的屬性名捎迫,View類型,參數(shù)類型表牢,以及該方法所屬的類)窄绒;
- ./build/intermediates/data_binding_dependency_artifacts/debug/dataBindingMergeDependencyArtifactsDebug/out目錄
- 包含兩類文件module-br.bin和module-setter_store.json;文件內(nèi)容同上崔兴;
- ./build/intermediates/data_binding_base_class_log_artifact/debug/dataBindingGenBaseClassesDebug/out目錄
- 包含一個(gè)文件module-binding_classes.json彰导;包含從XML名稱到ViewDataBinding類的映射關(guān)系(包括XML中變量類型);
- ./build/intermediates/data_binding_base_class_log_dependency_artifacts/debug/out目錄
- 包含依賴module敲茄,依賴庫(kù)的binding_class.json文件位谋,文件內(nèi)容同上;
- ./build/intermediates/data_binding_layout_info_type_merge/debug/mergeDebugResources/out目錄
- 包含了XML中變量部分以及綁定表達(dá)式信息堰燎,不包含View信息掏父;
- ./build/intermediates/data-binding/debug/bundle-bin目錄
- 最終產(chǎn)物
- BR文件
- 包含變量名和屬性名(@Bindable注解過(guò)的getter方法)對(duì)應(yīng)的ID;
- Binding/BindingImp文件
- XML文件對(duì)應(yīng)的綁定類秆剪,實(shí)現(xiàn)了運(yùn)行時(shí)自動(dòng)更新UI的邏輯赊淑;
- DataBindingComponent文件
- 如果BindingAdapter注解在實(shí)例方法上,會(huì)在該接口中生成獲取該實(shí)例的接口方法仅讽;
- DataBinderMapperImpl文件
- 包含了layout對(duì)應(yīng)的id到Binding類的映射陶缺,XML的rootView的tag到layout的id的映射,BR中的id到屬性名的映射洁灵;
- BR文件
總結(jié)
- 網(wǎng)上資料和驗(yàn)證結(jié)合來(lái)看饱岸,整體流程沒什么變化,除了一些細(xì)小的差別(比如Binding類又多了BindingImp子類)徽千;
- 流程
- 開發(fā)階段:主要涉及兩部分苫费,XML(layout和data標(biāo)簽)和注解;
- 資源處理:將XML拆分成兩部分:一部分為layout文件罐栈,最終打包到apk中的layout文件黍衙,和傳統(tǒng)寫法差不多泥畅,唯一不一樣的就是相關(guān)View的Tag會(huì)改成binding格式荠诬,這個(gè)是編譯期和運(yùn)行時(shí)的紐帶;另外一部分是layout-info文件位仁,包括變量和綁定表達(dá)式相關(guān)信息柑贞;
- 注解處理:先處理綁定注解(除Bindable)生成setter_store.json文件;再根據(jù)layout-info文件和setter_store.json文件處理綁定表達(dá)式聂抢,生成Binding/DataBindingComponent文件钧嘶;再處理Bindable注解,生成BR文件琳疏;再生成BindingImp文件(這個(gè)是個(gè)人猜測(cè)有决,因?yàn)锽indingImp的邏輯是要根據(jù)BR值生成dirtyFlag)闸拿;再生成DataBinderMapperImpl文件;
存疑
- DataBindingInfo文件及BindingBuildInfo注解有什么用书幕?
- DataBindingComponent不建議使用新荤,在實(shí)例方法上注解BindingAdapter,還不如直接在對(duì)應(yīng)的Activity中對(duì)可觀察數(shù)據(jù)源掛監(jiān)聽做特殊邏輯台汇;