登录

去注册

登录

注册

去登录

注册

每日一问 有没有使用过 DataBinding ,有什么优点、缺点,遇到过哪些坑?

xiaoyang   2019-06-26   收藏

1. 谈谈 DataBinding 的体验;

2. 遇到的坑;

3. 有什么优缺点。


本周1/3。

4

之前写过这个,贴过来


DataBinding是谷歌官方发布的一个框架,基于页面数据直接绑定的mvvm框架,最初接触其时被惊艳到了,其可以在xml文件直接绑定数据,通过Binding类直接拿到有id的控件,页面对数据的监听可以直接修改数据就能改变页面的数据,即使页面有多处使用到。但我现在决定弃用他了。下面一一列出理由。

1.编译延迟

DataBinging的编译不是及时的,我们在xml文件写好布局后,并不能直接就可以找到xml文件对应的Binding类,而要 Rebuild Project后才能找到Binding类,在xml文件添加某个控件的id后,也不能直接引用这个控件,也要Rebuild Project,实际上对xml文件的任何修改,都要Rebuild Project,databinding的相关才会生效,而不像R文件,我们修改后不必做额外的操作,R文件就会更改。而这会影响到编码速度。

2.无用功能多

DataBinding可以在xml文件直接绑定点击事件,可以在属性被改变时(DataBinding的方式改变)触发绑定的事件,然而这些看起来很美的功能,实质上从没被我使用过。

3.布局文件复杂

我们可能会写下如下代码:

通过网络请求获取到数据实体类后,使用mBinding.setBean(bean);来把数据设置上去,然而当我们要对获取的时间做一些格式上的设置的时候,我们就要先写好一个时间转换的类,再如下调用:

当然你也可以在实体类的get方法里做处理,但DataBinding的处理确实要麻烦些。因为DataBinding直接支持的函数很有限。

而如果没使用DataBinding,我们直接在set时做下格式处理就好了。

还有一种情况,例如界面要如下显示:"今日待办(10)",然后后台给我们的接口返回的是10,那么我们在DataBinding上要如此做:

其中a和b分别是定义在资源文件的"今日待办("和")",而不能直接在XML文件拼接。

4.多模块开发

如果以上问题都是些不够方便的小问题,我还可以忍受,那它在多模块开发上的问题是我放弃它的最主要原因。

DataBinding在多模块开发的时候,有这样一个机制:

  • 如果子模块使用了DataBinding,那么主模块也必须在gradle加上配置,不然就会报错;
  • 如果主模块和子模块都添加上了DataBinding的配置,那么在编译时,子模块的XML文件产生的Binding类除了在自己的build里会有一份外,在主模块下也会有一份。

那么,如果主模块与子模块都有一个layout根目录的activity_main.xml,主模块生成的ActivityMainBinding会是根据子模块的文件生成的!这种情况我们还可以通过让主模块和子模块使用不同的命名,那么下面这个问题就跟要命了:

如果子模块的某个xml文件使用了一些第三方的控件,那么主模块由于也会生成这个文件的Binding类,并且其会有第三方控件的引用,这时候由于主模块没有引入这些控件,就会报错,解决办法是在子模块应用第三方控件的时候,使用api的方式应用,这样主模块就坚决引用到了这些第三方控件,这是这样违背了解耦的原则。

回复
陈小缘 : @xujiafeng 

赞~d(* ̄▽ ̄)===b

2019-06-24 回复
xujiafeng : @xujiafeng 

多模块开发体验屎一样~

2019-06-24 回复
3

我们项目采用的是 kotlin && databinding 处理。
可能你会疑问,既然用的是 kotlin,为啥没有用 kotlinx?新的页面当然是用的 kotlinx 啦,但我们有相当庞大的历史代码,并且我们的通用 adapter 其实也是基于 databiinding 来封装的。


坑的话,其实真挺多的,随便说点。
1. 在不同版本的 AS 和 gradle 上可能表现形式不同,因为项目的组件化做的并不是非常彻底,所以我们在办公室一台性能小怪兽上写了一个脚本,让同事每次编译都放在了服务器上。所以就经常会出现一个服务器的 gradle 版本和本地的 gradle 版本不一致,导致出现在服务器上就是可以编过,但本地就是编译要报异常,这个问题在组内现象比较普遍;
2. 第二个是一个比较容易让人出错的点,那就是我们习惯在 xml 文件里面去做一些操作,常见的比如给 TextView 设置 text,我们经常会有一些数据是 int 的,导致在 xml 里面没有转换,而用正常的方式肯定编译器会直接报错,没有这个 resource。(额,可能这个并不能算作一个坑吧)
3. 错误定位可能不一定准确。通常来说,databinding 的编译错误会出现一大堆编译生成的文件找不到,但一般在最后都能找到准确的错误信息。但是!!!这个并不一定,笔者就遇到过无论如何都找不到错误的提示的,具体笔者忘了是在什么样的情况下了,这种错误通常是在 xml 里面直接出现的问题,需要我们一个一个文件的查看,而且通常一遍还看不出来。
4.在低版本的 AS 上每次需要 clean 一下才可以引用。这个我看 @xujiafeng 有说到,但这个并不是一定的,据我这边实测,之前我使用的 AS 版本有问题,但我升级后得到了解决。
5. 代码不是非常方便维护。我姑且把优缺点这个问题忽略了,我主要是来吐槽的。我们会有相当一部分代码的渲染 UI 逻辑是放在 XML 里面的,在部分非常复杂的页面,这个就非常鸡肋了,比如一个商城的详情页,你这样处理可能会出现非常非常多的XML 逻辑,而这样的逻辑会让接手代码的人非常痛苦,尤其是做较大的 UI 变动的时候。所以我在使用一段时间后,我基本现在不会直接在 XML 里面写逻辑,而会选择在代码里面。
6. BindingAdapter 不好维护,我们通常会用到 @BindingAdapter 方式来做一些公用逻辑,而不是直接去把逻辑放在页面通过设置属性来使用它,这样就会出现这些公用逻辑比较难维护,当然,这极有可能是我们项目的历史问题,但我觉得这算是一个坑点了。不知道有没有人出现这样的属性在 XML 里面没有提示的情况。就像你自定义 View Styleable 名字不唯一一样。

哎,个人能力有限,就想到哪儿说到哪儿了。可能有不少其实并不是 databinding 的坑,是个人使用问题,还往明白的人能直接指出。PS:再给我一个机会,我不想在用 Databinding.

回复
nanchen2251 : @鸿洋 

然后自己在逛论坛又发现了一个问题。https://issuetracker.google.com/issues/119661177

2019-06-25 回复
nanchen2251 : @陈小缘 

大佬,想加你微信。我的微信:nanchen2251

2019-06-25 回复
陈小缘 : @nanchen2251 

赞~d(* ̄▽ ̄)===b

2019-06-25 回复
鸿洋 : @nanchen2251 

thx~

2019-06-24 回复
nanchen2251 : @nanchen2251 

然后我又重新整理了一篇:https://mp.weixin.qq.com/s/GgDLJTU8x0txkSgGEtp6VA

2019-06-24 回复
1

我现在的项目采用的就是mvvm+DataBinding,感觉view层的代码少了很多,同时对应的@BindingAdapter里面就会增加很多相应的逻辑处理,不过我觉得相对于来说代码更加清晰,而且用DataBinding封装了个adapter之后RecycleView用起来无处不在,贼鸡儿舒服,至于说xml里面设置参数什么的确实很坑,有时候就没有提示,关于DataBinding生成辅助类,我有心得,就是在创建对应activity的时候layout的时候xml中的<precourier new';font-size:15.0pt;"=""><layout </precourier><data></data></layout>标签一定要创建出来,这样在activity中就会直接找到xxActivityBinding.另外配合livedata使用体验也很不错.至于缺点的话其实每个东西都有,只是你习惯了,而一个新东西你没有习惯,你也不敢尝试,只是看着别人的使用经验,压根没用过,就放弃了,我觉得新东西就需要尝试,只有自己尝试了才会知道好不好.

回复
1

我们项目是用databing、kotlin及模块化方式开发。

主要的坑有:1.如果在不同工程下的layout文件名相同,gradle编译之后会报错并无法运行项目;

2.单元测试、功能测试等等方面的困难,因为大多数的东西可以放在xml文件中处理,所以在测试item的方面的东西难度加大;

3.只有在编译时,才能检测xml写法是否正确和警告提示,同时编译速度真的慢。

优点:

1.由于livedata和viewmodel的特性,能自动监听数据变化,事件监听等等,但是由于每次数据变化,会自动重新绘制View,会引发性能方面等问题;

2.ViewModel跟Xml文件来交互,所以事件处理和数据处理参杂一起,需要封装处理分离和加大单元测试覆盖难度;

3.@BindingAdapter的特性,对控件的处理更加方便。

回复
1

第一次发言,萌新一个,不知道这个是什么,就是过来看看,看看能不能学点啥,嘤嘤嘤!

回复
0

我遇到印象比较深的一个坑,ViewModel类的类名如果超过19个字母就会编译报错。

回复
0

我司采用的就是 mvvm  databind 模式。

    我是直接从mvc 变化到 mvvm,体验就是蹩手,接受,优化,挺爽。


优点:

1. 列表写起来特别爽,并且清晰,

  提一下这个 https://github.com/evant/binding-collection-adapter


2.@bindadapter 玩出新高度。

    1. 各种通用的属性统一处理。

    2.  状态相互配合(不过要统一管理,不然乱的一笔)


3. 展示 editext 直接写 不用监听watch 回调了。


4. 业务控件。 


缺点:

    1.windows  在xml 中必须使用@string/xxxx

    2. 复杂的业务不直接写xml中。

    3. 编写代码层级变多( 其实不是事,可以自己建立模板 一键代码生成)


想到在写。 todo'


 



 

回复
0

在自己的项目中使用了近两年半了,公司项目只用过优点一....

优点 1.不用再findviewbyid,和使用butterknife 生成大量的无关代码

         2.可以和viewmodel结合,代码很简洁,逼格很高。。

缺点  1.当显示一个字段需要很多逻辑判断时不太实用,需要另建立方法处理然后引用

          2.很多点击事件也需要提一个方法出来,就像最开始那个哥们说的,后期看起来逻辑不是很清晰,也不方便维护。

          3.报错也不方便定位问题。


所以实际公司项目只用到了替代了findviewbyid的功能,然后结合mvp。可能有更好的方式解决那些缺点问题,希望躺过坑的人指出..

回复
0

1.我们的新项目采用的是 kotlin &  DataBinding   ,似乎二者的兼容还有一些问题,总体而言体验还是不错的


2遇到的坑:

①比如新写了一个DataBinding (就是头尾标签是layout的)的XML文件,需要Rebuild一下才会生成对应的Bing类

②XML中有写错的,有时AS并不能直接打印出错误(可能这个不是DataBinding的问题),需要用./gradlew build --stacktrace才能打印具体的错误信息

DataBinding中的控件ID自动转换为驼峰命名法命名,用起来有点难受,比如说需要查找某个控件哪里用了,正常的Ctrl+f拷入控件ID,能看到使用的个数,上上下下就能定位到具体位置了


3.优点

①很多相同布局的点击事件,写一次就好了

eg:以返回按钮为例(当然很多标题栏的返回键都是封装到一起,但是由于本人所在公司设计较多,也没有很好的规范,整个标题栏的封装就没有意义了 

<prelucida sans="" typewriter';font-size:11.3pt;"=""><?xml version="1.0" encoding="utf-8"?>
<layout>

<data>

<import type="androidx.appcompat.app.AppCompatActivity"/>
</data>

<!--<span宋体';">必须集成DataBing<span宋体';">的基类才生效-->

<ImageView
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/iv_back"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:src="@drawable/icon_back"
android:onClick="@{v -> ((AppCompatActivity)v.getContext()).finish()}"
android:paddingStart="15dp"
android:paddingEnd="15dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/></span宋体';"></span宋体';"></prelucida></layout>  

需要返回键的地方include进去就可以了,同理比如说很多现实用户头像和用户信息的地方,都需要跳转到个人主页...

这种 相同的界面和相同的跳转用起来是真的爽

②设置数据时,代码里只需要把请求的Bean对象设置一下就好了,具体的赋值在XML中就能完成了,使用这个我现在更喜欢MV的模式开发了,MVP在项目里使用起来并没有传出来的那么好用,个人理解哈

③我也想加下大佬微信[坏笑] @陈小缘啦啦啦 @nanchen2251 

大佬

回复
0

个人觉得坑点比优点多,比较适合需求简单的项目,如果项目规模大,需要分模块开发就不好用了。这个东西主要是为了分离view层的代码,但是目前来看还是不太好用。

回复
0

体验: 确实很舒服,可以直接绑定View层和Data层,将数据更新到的操作变得简单

  更方便的添加监听回调,直接加一个BindingAdapter,导出都能监听

坑:

1.  XML 中 使用 include 标签添加通用视图时,getRoot() 方法没办法识别。同时相应的,include 标签下视图的DataBinding也是存在问题。

2. 维护起来很难,这个虽然算是开发的问题,但是因为编辑器支持的问题,自定义的XML方法没有办法跳转。使用BindingAdapter之后想要找到很麻烦

3. 错误信息不明确。


确实是一把双刃剑

回复
0

周末写盘Android的时候想用一下,后来还是放弃了选择了livedata和viewmodel然后observer,感觉更加舒适

回复
0

没有[污]

回复
0

体验很nice

坑倒是没什么,编译找不到类说明xml写的有错误,注意看一下日志就能知道哪行报错,顺着改就好了。


回复
0

体验:在使用Kotlin之前使用过DataBinding,目的是为了减少findViewById,
坑:遇到的坑是经常找不到系统编译的Binding类(编译失败),
优点:数据的双向绑定据说很nice,但是我还没有体验(还没有学习)

回复
0

体验:很舒服,有恋爱的感觉

坑:动态加载布局找不到辅助类

优:1、可以实现view和data的数据双向绑定

       2、不用在写findViewById

       3、支持lambda表达式

       4、可节省activity和fragment中获取控件,赋值,添加监听所需的大量代码

缺:xml布局中如果控件出现问题(例id命名重复),当出现报错的时候是在java层,貌似在崩溃的log中没有明确指出layout布局中出现什么问题


回复
yoyiyi : @小龙虾炒大蒜 

楼主是人才

2019-06-25 回复

删除留言

确认删除留言,会导致相关评论丢失?

取消 确定