【问题标题】:Android DataBinding 3.0.1 calling method on observable variable causes wrong code generated that leads to NPEAndroid DataBinding 3.0.1 在可观察变量上调用方法导致生成错误代码,导致 NPE
【发布时间】:2018-05-17 18:59:13
【问题描述】:

我写过这样的布局:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>

        <variable name="vm"
                  type="example.Vm" />
    </data>

    <android.support.constraint.ConstraintLayout android:id="@+id/root"
                                                 android:layout_width="match_parent"
                                                 android:layout_height="match_parent">

        <ImageView android:layout_width="wrap_content"
                   android:layout_height="wrap_content"
                   android:layout_marginEnd="16dp"
                   android:layout_marginRight="16dp"
                   android:onClick="@{() -> vm.observableField.buttonClicked()}"
                   app:layout_constraintBottom_toBottomOf="parent"
                   app:layout_constraintRight_toRightOf="parent"
                   app:layout_constraintTop_toTopOf="parent" />

    </android.support.constraint.ConstraintLayout>
</layout>

在 onClick 参数中,我在 example.Vm 上调用具有此类字段的方法:

public ObservableField<SomeClass> observableField = new ObservableField<>();

Android 数据绑定生成了这样的代码:

// Listener Stub Implementations
// callback impls
public final void _internalCallbackOnClick(int sourceId , android.view.View callbackArg_0) {
    // localize variables for thread safety
    // vm != null
    boolean vmJavaLangObjectNull = false;
    // vm.someClassObservable
    android.databinding.ObservableField<biz.i20.fire_android.feature.act.SomeClass> vmSomeClassObservable = null;
    // vm
    biz.i20.fire_android.feature.actscreen.ActVm vm = mVm;
    // vm.someClassObservable != null
    boolean vmSomeClassObservableJavaLangObjectNull = false;
    // vm.someClassObservable.get()
    biz.i20.fire_android.feature.act.SomeClass vmSomeClassObservableGet = null;



    vmJavaLangObjectNull = (vm) != (null);
    if (vmJavaLangObjectNull) {


        vmSomeClassObservable = vm.someClassObservable;

        vmSomeClassObservableJavaLangObjectNull = (vmSomeClassObservable) != (null);
        if (vmSomeClassObservableJavaLangObjectNull) {


            vmSomeClassObservableGet.buttonClicked();
        }
    }
}

正如您在此处看到的,数据绑定编译器使用null 值初始化变量vmSomeClassObservableGet,然后不会从vmSomeClassObservable 获取它的值。 我可以通过在ObservableField 上显式调用.get() 来解决这个问题,但是它会导致编译器警告:

警告:警告:不要在 ObservasbleFields 上显式调用 'get()' 在一个表达式中。此支持将很快被删除。 'vm.observableField.get()'

我该如何解决这个问题?好像是bug。

【问题讨论】:

  • 这看起来像一个错误。如果您在表达式中使用“observableField.get()”,您应该只会看到该警告。

标签: android data-binding android-databinding


【解决方案1】:

您无需使用 ObservableField 包装该类即可从您的布局中调用它。

我会将您的字段替换为:

public SomeClass observableField = referenceToSomeClass;

(我会将observableField 重命名为更合适的名称,但为了让答案更清楚,我这样保留)

【讨论】:

  • 我已经打包好了,因为我的任务需要打包,当然。
  • 另外,我已经重命名了字段以显示原理,而不是因为它在 NDA 下公开我的项目信息。
  • 关于字段命名,我的意思是我会在建议的更改后重命名它。很明显,选择SomeClass 和其他名称来说明您的观点:) 话虽如此,单击方法在可观察字段中感觉有点奇怪。我同意这看起来像一个错误。没有警告的一种可能的解决方法是为点击处理程序和类似的东西设置一个特定的变量,实现一个特定的interface。如果不知道SomeClass 的具体情况,我想不出更好的答案。
  • 我正要建议你打开一个错误,但我看到你已经完成了:) 在这里链接它以便能够跟踪它issuetracker.google.com/issues/70145419
  • 顺便说一句,你能给这两个问题加注星标吗?
猜你喜欢
  • 1970-01-01
  • 2011-06-21
  • 2021-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多