Android 混淆与反射

起因

前一段时间比较空闲,于是就把Android的MVVM给封装了一下。在我的框架里面‘vm’这个参数是肯定存在的,但是又不想在业务逻辑中进行赋值vm。于是乎就通过反射的方式在BaseActivity中通过反射的方式来进行处理了。在Debug版本跑的飞起,在准备上uat 版本的时候出现了闪退的问题。

先说解决方案

在 proguard-rules.pro 排除这2块的混淆

-keep class **.*Binding {*;}
-keep class **.*BindingImpl {*;}

PS:
我这里直接把整个类都进行了排除混淆,严谨一点的应该单独配置 setVm的方法的混淆

排查过程

首先查看报错信息,发现是我自定义的BindingAdapter 空针问题,当时以为我传入的 实体类出现了混淆问题,把实体给排除混淆发现没有问题。 那么引用 ‘vm.scanStatus’为空 会不会直接原因就是vm为空?(代码①)

后面进行了代码测试,果然vm为空。那么进行业务层面的主动赋值会不会就OK了呢?答案是肯定的,是OK了的。那么原因就很明显了,肯定就是我反射的时候寻找setVm的方法是被混淆掉了。

原因找到了,那么剩下就是解决的方案了,我们知道的 在DataBinding中的layout会被映射到 xxxBinding上,而相关实现就在xxxBindingImpl上。那么把这2块的混淆给去掉不就ok了吗?加上混淆试一下 果然好用

部分源码
代码①



@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 设置vm参数
    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) })
}

你可能感兴趣的:(Android 混淆与反射)