关于Android databinding的调查总结

在2018年的时候,对于Android DataBinding进行了一段时间的研究(说是研究,大概也就持续了不到两周的时间),踩了一些坑,当时把总结的东西都放在印象笔记里面了,今天偶然的机会,又翻到了以前总结的东西,感觉应该分享出来,希望能够对遇到同样类似问题的朋友有所帮助。

总体分为三部分:

应用场景,缺点,优点

一、应用场景

1.画面字段多而杂,且基本都是展示为主,交互较少。

二、缺点

1.编译失败报错时提示信息很蛋疼

比如:

这个错实际上是因为在画面上调用方法的写法有问题,没有通过编译造成的。

代码如下:

<TextView

    android:id="@+id/tv_order_state"

    android:layout_width="wrap_content"

    android:layout_height="wrap_content"

    android:layout_alignParentRight="true"

    android:textSize="@dimen/common_font_size_level_3"

    android:textColor="@{orderDetailActivity.showOrderStateTextColor()}”/>

但是报错却基本上是跟这个问题无关的信息,最有价值的地方就是在报错的信息中能直接定位到

android:textColor="@{orderDetailActivity.showOrderStateTextColor()}”/>

这一行,其余的信息基本都没啥用。

2.xml编辑器的静态错误提示页很蛋疼。运行没有问题的代码也会给出红线波浪号(这是18年的时候的编译器,现在要比过去智能不少,可能在最新的3.3版本的AS中已经看不见截图中的红色波浪线了)

比如:

红线出现,提示信息是:

但是实际代码是可以运行的,并且运行也没有问题。

3.写法不标准时,提示的错误信息无法提供参考

比如,按照 databinding 的官方说明文档写的代码:

最后在编译成功之后会有警告:

网上的解决方案是,将 @BindingAdapter 中的 “binding:” 属性前缀去掉。

个人感觉很山寨。但是目前也没有发现其他的解决办法。

4.@DataBinding 的表达式与语法中,暂时不支持 mipmap 资源。

也就是说你可以在布局文件中这么写:

bind:error="@{@drawable/list_default}"

但你不能这么写:

bind:error="@{@mipmap/list_default}"

写mipmap会报错。如下:

很是无语。

5.xml 中的代码提示没有 java 文件中的代码提示强大。

6.xml中如果引入的工具类需要用到其他非 pojo 类型的对象,如何注入?

答:按照正常的方式注入,与pojo没有任何区别,但是有的时候受限于 IDE 的一些 bug,会造成很多的问题,比如:明明已经生成的方法,调用的时候 IDE 中提示报错。此时需要重启 IDE,才能恢复正常。

7.在画面模板文件中,不能直接使用对应画面的方法,需要进行注入,这点与AngularJS相比稍有差距。

8.对于不熟悉框架的人来说,很多问题定位困难。

比如 在商品详情画面中,使用了banner控件,但是图片死活就是显示不出来,正常写法的话,应该可以显示出来。但是用数据绑定框架之后,就显示不出来,这种问题。

后来发现不是banner控件的问题,而是忘记调用banner控件的start方法的问题。但是由于使用了数据绑定框架,所以这里会对排错造成一些干扰。

9.编译错误提示不友好:

比如遇到过一个问题:

提示:Error:(42, 34) Cannot find the setter for attribute 'bind:imageUrl' with parameter type java.lang.String on com.makeramen.roundedimageview.RoundedImageView.

但是在 BindingAdapter 明明声明了 bind:imageUrl 与 bind:error 但是指定 bind:imageUrl时就是报错。

提示是:无法找到 bind:imageUrl 的 setter ,但是明明已经用BindingAdapter声明了这个属性。

实际上真正的原因是:

参见url:http://blog.csdn.net/gdut_lemon/article/details/53330631

错误的提示实在是不友好。可以认为是基本没什么卵用。

10.对象的注入需要手动进行,有的时候会遗忘手动注入这一步。

比如:注入onClick事件时,虽然这样写了:

android:onClick="@{fragment::onAllCommentsClick}"

但是,在Java代码中如果忘记调用相应的注入 fragment 对象的方法,则这个监听器不会起作用。

binding.setFragment(this);

而这个监听器对象的注入,很容易遗忘,

因为在传统的开发中,我们本来就可以直接在控件中这样写:

android:onClick=“onBtnClick"

此时只要在相应的Activity中写一个方法:

public void onBtnClick(View v){

    // Do something

}

即可。这样反倒比DataBinding省了一步。

11.databinding框架不支持在 fragment 标签上使用框架提供的特性。也就是说我们不能把变量绑定到 fragment标签上。

如果我们这么做的话,首先在编译的时候会报错,错误信息就是:不能再 fragment 上使用数据绑定(错误的英文提示翻译过来的意思)

其次还有个问题就是,

当你试图定义一个 @BindingAdapter处理Fragment时,会报如下错误:

Error:(36, 24) 错误: @BindingAdapter bindFragmentParams(android.support.v4.app.Fragment,java.lang.String,java.lang.String) is applied to a method that doesn't take a View subclass as the first or second parameter. When a BindingAdapter uses a DataBindingComponent, the component parameter is first and the View parameter is second, otherwise the View parameter is first.

上面的话翻译过来就是:如果使用BindingAdapter定义新属性的话,第一个参数要么是 DataBindingComponent 要么是一个 View,其他情况不行。出错的代码如下:

@BindingAdapter({"bind:fragmentParamKey", "bind:fragmentParam"})

public static void bindFragmentParams(Fragment fragment, String paramKey,String param) {

    Bundle bundle = new Bundle();

    bundle.putString(paramKey,param);

    fragment.setArguments(bundle);

}

12.当布局中用 include 进行嵌套时,使用 binding 对象无法通过 id 获取 include 布局中的控件。

13.重构带参数的字符串等资源时,无法直接通过重构的方式将databinding 布局文件中的对应的变量名一起重构。比如:

<TextView

    android:id="@+id/tv_order_total_fee"

    android:layout_width="wrap_content"

    android:layout_height="wrap_content"

    android:layout_centerVertical="true"

    android:layout_toRightOf="@+id/tv_sum_title"

    android:textColor="@color/common_warn_font_color"

    android:textSize="@dimen/common_font_size_level_2"

    android:text="@{@string/common_item_price(orderDetailModel.totalAmount)}"/>

这里,如果再 strings.xml 中重构字符串变量,将 common_item_price,重构为 common_item_price_with_symbol,此时直接通过AS的重构是无法将这里的红色部分代码重构的。必须自己手动修改。

14.CustomListView(用于在ScrollView中嵌套的列表控件)在使用 databinding 的开发模式开发Adapter时有坑。主要体现在:当列表项中的 TextView 控件的文字多于一行时,列表高度的计算有问题,导致列表显示不全,(列表的实际显示高度比列表真正的高度小,导致部分内容截断)。

而使用传统的holder模式来写 adapter 时,则没有此问题。

三、优点:

1.代码变得精简

订单详情画面,用DataBinding框架改写之后,Java代码 354->264   布局文件:537->510 (代码的减少很大原因是因为进行了布局的优化,所以这部分其实正常情况下是不会减少反而会有所增加的。在没有优化布局之前大概是 537->550+,也就是多了大概二十几行)

所以使用databinding绑定之后的代码量大概减少了70行左右,整体891->814,减少了10%的代码量

2.页面上的逻辑变得简单,清晰。

就好比 JQuery 改为 Angular 的那种感觉。有了数据绑定,就不需要再写大段大段的代码进行控件的数据绑定处理了。

3.省去了 findViewById (实际上就是做了 ButterKnife 这种注解框架帮我们做的事,但是 databinding 在实际使用的时候更加方便,因为它让我们连注解都不用写)

在使用了 databinding 的布局文件中,只要我们为一个控件指定了 id,那么在 相应的 binding 对象中就会生成一个与相应id对应的控件。我们可以通过binding对象直接引用这个对象。

猜你喜欢

转载自blog.csdn.net/awy1988/article/details/88543242
今日推荐