起因
前一段時(shí)間比較空閑略就,于是就把Android的MVVM給封裝了一下吗跋。在我的框架里面‘vm’這個(gè)參數(shù)是肯定存在的桌粉,但是又不想在業(yè)務(wù)邏輯中進(jìn)行賦值vm旦袋。于是乎就通過反射的方式在BaseActivity中通過反射的方式來進(jìn)行處理了。在Debug版本跑的飛起瞄沙,在準(zhǔn)備上uat 版本的時(shí)候出現(xiàn)了閃退的問題己沛。
先說解決方案
在 proguard-rules.pro 排除這2塊的混淆
-keep class **.*Binding {*;}
-keep class **.*BindingImpl {*;}
PS:
我這里直接把整個(gè)類都進(jìn)行了排除混淆,嚴(yán)謹(jǐn)一點(diǎn)的應(yīng)該單獨(dú)配置 setVm的方法的混淆
排查過程
首先查看報(bào)錯(cuò)信息距境,發(fā)現(xiàn)是我自定義的BindingAdapter 空針問題申尼,當(dāng)時(shí)以為我傳入的 實(shí)體類出現(xiàn)了混淆問題,把實(shí)體給排除混淆發(fā)現(xiàn)沒有問題垫桂。 那么引用 ‘vm.scanStatus’為空 會(huì)不會(huì)直接原因就是vm為空师幕?(代碼①)
后面進(jìn)行了代碼測試,果然vm為空诬滩。那么進(jìn)行業(yè)務(wù)層面的主動(dòng)賦值會(huì)不會(huì)就OK了呢霹粥?答案是肯定的,是OK了的疼鸟。那么原因就很明顯了后控,肯定就是我反射的時(shí)候?qū)ふ襰etVm的方法是被混淆掉了。
原因找到了空镜,那么剩下就是解決的方案了浩淘,我們知道的 在DataBinding中的layout會(huì)被映射到 xxxBinding上,而相關(guān)實(shí)現(xiàn)就在xxxBindingImpl上吴攒。那么把這2塊的混淆給去掉不就ok了嗎张抄?加上混淆試一下 果然好用
部分源碼
代碼①
<TextView
android:id="@+id/connect_step_3"
style="@style/AppTextView.Connect.Step"
bindIWarmErrorStep3="@{vm.scanStatus}"
android:text="@string/connect_step_3" />
@JvmStatic
@BindingAdapter(value = ["bindError"], requireAll = false)
fun bindError(view: TextView, status: Status) {
when (status) {
Status.NotFound -> {
view.visibility = View.VISIBLE
view.setText(R.string.unfind)
}
Status.ConnectedFailed -> {
view.visibility = View.VISIBLE
view.setText(R.string.connect_failed)
}
else -> view.visibility = View.GONE
}
}
代碼②
protected open fun initViewModel(vm: VM) {
val activity = this@BindActivity
// dataBinding 設(shè)置vm參數(shù)
ReflectionUtils.invokeMethod(dataBinding, "setVm", vm, viewModelClass)
vm.loadingStatus.observe(activity, Observer { changeLoadingStatus(it) })
vm.errorStatus.observe(activity, Observer { changeErrorStatus(it) })
vm.successStatus.observe(activity, Observer { changeSuccessStatus(it) })
vm.emptyStatus.observe(activity, Observer { changeEmptyStatus(it) })
vm.toastMessage.observe(activity, Observer { showToast(it) })
}