Android项目中能否同时使用Butter Knife和Data Binding?
不需要全量重构为Data Binding,Butter Knife和Data Binding完全可以共存,你遇到的运行时Butter Knife绑定值为null的问题是启用Data Binding后的常见配置/调用顺序问题,按以下方案排查即可解决。
崩溃核心原因
开启Data Binding后,布局会默认走Data Binding的布局解析逻辑,如果你旧的Activity/Fragment没有调整绑定调用顺序,或者布局结构做了多余修改,就会导致Butter Knife找不到对应View。
可行的共存解决方案
- 调整绑定调用顺序:在仅使用Butter Knife的旧页面,保证
ButterKnife.bind()调用在setContentView()之后即可;如果同一个页面混用两种绑定方案,调用顺序必须为:先初始化Data Binding实例,再将Data Binding的根View传入ButterKnife完成绑定,不要直接在setContentView()之后调用ButterKnife.bind(this) - 显式关闭冲突配置:如果你不需要单独使用View Binding,在模块级build.gradle的android配置块下显式关闭View Binding,避免两者和Butter Knife产生id解析冲突:
android { ... buildFeatures { dataBinding true viewBinding false } }
- 保留旧布局原有结构:没有用到Data Binding的旧布局不要额外添加
<layout>根标签包裹,加了<layout>的布局会被编译为Data Binding专属布局,Butter Knife无法直接解析到内部的View id,会直接导致绑定失败 - 已加
<layout>标签的旧布局适配方案:如果已经给旧布局加了<layout>根标签,绑定Butter Knife时需要传入Data Binding实例的根View,示例代码如下:
// Java 页面示例 ActivityOldBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_old); ButterKnife.bind(this, binding.getRoot());
// Kotlin 页面示例 val binding = DataBindingUtil.setContentView<ActivityOldBinding>(this, R.layout.activity_old) ButterKnife.bind(this, binding.root)
迁移建议
你可以按迭代节奏逐步迁移,不需要一次性替换全量Butter Knife代码:新增页面全量使用Data Binding,旧页面仅在迭代对应功能需求时再替换Butter Knife逻辑即可,不会影响现有功能的正常运行。
内容的提问来源于stack exchange,提问作者Sudip Sadhukhan
相关产品推荐
相关产品推荐

