MainActivityBinding 中的 ClassCastException

ClassCastException inside MainActivityBinding

当尝试向我的应用程序添加数据绑定时,我在 ClassCastException inside MainActivityBinding 后看到崩溃。这是堆栈跟踪:

com.myapp E/AndroidRuntime: FATAL EXCEPTION: main
                                                                  Process: com.myapp, PID: 15524
                                                                  java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.CharSequence
                                                                      at com.mayapp.databinding.MainActivityBinding.executeBindings(MainActivityBinding.java:553)
                                                                      at android.databinding.ViewDataBinding.executeBindingsInternal(ViewDataBinding.java:379)
                                                                      at android.databinding.ViewDataBinding.executePendingBindings(ViewDataBinding.java:351)
                                                                      at android.databinding.ViewDataBinding.run(ViewDataBinding.java:178)
                                                                      at android.databinding.ViewDataBinding.onViewAttachedToWindow(ViewDataBinding.java:146)
                                                                      at android.view.View.dispatchAttachedToWindow(View.java:17392)
                                                                      at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3319)
                                                                      at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3326)
                                                                      at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3326)
                                                                      at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3326)
                                                                      at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1658)
                                                                      at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1386)
                                                                      at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6733)
                                                                      at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
                                                                      at android.view.Choreographer.doCallbacks(Choreographer.java:723)
                                                                      at android.view.Choreographer.doFrame(Choreographer.java:658)
                                                                      at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
                                                                      at android.os.Handler.handleCallback(Handler.java:789)
                                                                      at android.os.Handler.dispatchMessage(Handler.java:98)
                                                                      at android.os.Looper.loop(Looper.java:164)
                                                                      at android.app.ActivityThread.main(ActivityThread.java:6541)
                                                                      at java.lang.reflect.Method.invoke(Native Method)
                                                                      at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
                                                                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

里面 main_activity.xml 我有以下内容:

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

    <data>
        <variable
            name="tiles"
            type="com.myapp.Tile[]" />
    </data>
    ...

Tile[] 带有下划线,给我 "Cannot resolve symbol ..." 错误,我选择忽略该错误,因为 docs 说:

Note: Arrays and a generic type, such as the Observable class, might display errors when there are no errors.

gradle 构建成功,但是,当我 运行 在模拟器或物理设备上运行应用程序时,出现上述错误。

当我从堆栈跟踪中跟踪 link 时,我实际上可以输入 MainActivityBinding。在很多代码中,我发现编译器标记了以下方法:

public boolean setVariable(int variableId, Object variable) {
    switch(variableId) {
        case BR.tiles :
            setTiles((com.myapp.Tile[]) variable);
            return true;
    }
    return false;
}

BR.tiles 有下划线,编译器告诉我:"Constant expression required".

这是一个错误还是我做错了什么?

定义整型变量,如

<data>
<integer
        name="tiles">integer
</integer>
</data>

因为您正在将整数值分配给 XML 变量。

When trying to add data binding to my app, I see a crash after a ClassCastException inside MainActivityBinding.

根据错误,您有一个计算结果为 intInteger 的绑定表达式,但属性需要 CharSequence.

I had the following expression inside my XML: android:text='@{tiles[0].getValue == 0 ? "" : tiles[0].getValue}' in order to print nothing if value == 0 else print value. Yet the "false side" of the ternary evaluates to an int. I put String.valueOf(tiles[0].getValue) and it works.

通常,如果您通过绑定表达式将 int 传递给 android:text,它可以正常编译,但是如果 int 不是字符串资源 ID,您就会崩溃那(ResourceNotFoundException)。我的猜测是,由于 "",数据绑定框架假设您想要 setText(CharSequence),并将三元结果显式转换为 CharSequence,然后当 Integer 时崩溃不能那样投。

就我个人而言,我正在放弃使用这种绑定表达式,而是填充某种真正的 "view model" 逻辑在 Java 中(更容易调试,更容易测试)和对其进行绑定,因此绑定表达式更简单。

I checked: BR.tiles is public static final int. So why does the compiler complain anyway?

这是个好问题。我原以为它是以 switch 不喜欢的方式声明的。