DataBinding最佳实践
本文会不定期更新,推荐watch下项目。如果喜欢请star,如果觉得有纰漏请提交issue,如果你有更好的点子可以提交pull request。
本文的示例代码主要是基于作者的经验来编写的,若你有其他的技巧和方法可以参与进来一起完善这篇文章。文章中大量参考和引用了DBinding权威使用指南的内容,如果你想了解更多建议深入阅读一下DBinding权威使用指南。
说明:下文中vm是view model的缩写
本文固定连接:https://github.com/tianzhijiexian/Android-Best-Practices
一、需求背景
开发者都希望可以更快更简单地编写代码,并且还希望代码的可维护性和健壮性能符合团队的期望。很多初创团队在发展多年后逐渐认识到了早期代码模式的弊端,并且在代码的组织结构上有了很多思考。
在模式方面,2015年大家开始争相讨论mvc,mvp,mvvm,期间谷歌也推出了自家的数据绑定框架databinding,借此来简化代码的编写。在这一片百家争鸣中,开发者十分希望能找到一个满足项目需求并且稳定可靠的框架来简化开发工作。
二、需求
开发者对于一个框架最看重的是下面几点:
- 能加快开发速度,屏蔽底层细节
- 代码可读性好,易维护
- 代码量越少越好,易阅读
- bug少,有不错的健壮性
三、实现
指定明确的分层
如果一个项目有了明确的分层结构,那么代码的可读性和可维护性会上升很多,它也是一个架构的基础。分层良好的的优点有很多,而且即使某天要更换框架,也不会伤筋动骨。
需要格外注意的是:只有当一个项目的成员都能明确项目的层级后才可以谈框架和模式,否则一个框架再优秀也无法在混乱中发挥出优势。

层名 | 内容 |
---|---|
view层 | 具体的view,activity,fragment等,做ui展示、ui逻辑、ui动画 |
vm层 | 具体的视图模型类,是view展示的数据的java映射,能被model层直接操作 |
model层 | 非ui层面的业务逻辑的实现。包含网络请求,数据遍历等操作,是很多具体类的抽象载体 |
DBinding是一个databinding的扩展类,它提供了快速绑定vm和通过vm维持多个页面之间数据同步等功能,并且它还有强大的as插件来做支持,因此本文将选择它作为mvvm框架。
通过数据来更新UI
目前流行的做法都是通过数据来驱动UI,其优点在于方便做单元测试和多人协作,对bug的定位也有比较好的帮助。mvvm是一个抽象的概念,它目前最稳定可靠的实现就是databinding,在用databinding之后,我已经很少到view层定位bug了。databinding的代码由xml代码和java代码构成。
layout:
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<!-- 定义变量: private org.kale.vm.UserViewModel user -->
<variable
name="user"
type="org.kale.vm.UserViewModel"
/>
</data>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@{user.name}"/>
</layout>
Activity:
private UserViewModel mUserVm = new UserViewModel();
@Override
protected void onCreate(Bundle savedInstanceState) {
DBinding.bindViewModel(this, R.layout.activity_main, mUserVm);
mUserVm.setName("kale"); // textview中就会自动渲染出文字了
}
layout文件中的vm取名应该和layout文件名字有关联,layout文件的名字也应该和activity的名字有关,这样可以方便定位问题和查找逻辑。layout中vm的参数完全可以模仿之前取id名字的思路,只不过千万不要加view的缩写,出现tv_username或username_tv就闹笑话了。layout文件中强烈不建议写import语句,vm类名强制写全称。至于java代码就十分简单了,没有过多的要求,只要对vm操作即可更新ui。
通过代码模板快速生成layout文件
为了快速产生mvvm的layout文件,我利用了as提供的代码模板功能。

强类型语言和弱类型语言的一个差异(仅仅是差异)就是在于IDE可以帮你做很多限制,databinding本身是相当灵活的,支持双向绑定,支持xml中写逻辑等操作,但是我这里利用插件或者是其他的方式强烈禁止在xml中写方法和特殊逻辑,对于import我只允许了View这一个类的import。对于双向绑定,我建议你在编码的时候就应该有所警惕,最好能有注释,方便你的同伴进行定位问题。
如果你是一人开发一个不需要维护的应用,那么xml中随便你怎么写,但如果你是团队开发,你会发现那些在xml中的逻辑很可能是团队合作的灾难。当然了,如果你已经通过某种文档或者是其他的标准化方式来限制和规定xml中的逻辑格式,那么我倒是觉得是可行的。
自由是在限制之中的,如果没有限制那么就没有社会。
四、总结
我经历了项目从mvc到mvp,然后变成mvvm,最后到mvpvm的各个阶段,在每个阶段中我也花了大量的时间去发现问题解决问题,为后续的扩展和灵活性做了很多的工作。在做这些事情的时候我渐渐发现,无论你采用什么模式,你都必须有明确的分层的概念,其实大到分层小到单一职责概念,都是在提升代码可维护性。在现在这个时期,我的建议是中小型公司可以放心尝试databinding,大型公司的话因为体量和人员的问题很难会改变模式。当然了,如果目前你的代码本身就有很好的可维护性,我也不建议因为技术的新颖而动项目,因为我们的目的不是尝鲜和炫技,而是为了解决问题!
话说,你写了多少年的findViewById?
