【问题标题】:Any significant bug or issues with Android Databinding Library? [closed]Android 数据绑定库有任何重大错误或问题吗? [关闭]
【发布时间】:2015-08-31 23:18:01
【问题描述】:

任何使用 android 数据绑定库 (com.android.databinding:dataBinder) 的人都可以评论这个 beta 库吗? 在 android 开发者网站上说“它可能包含错误,并且可能不适用于您的用例,所以使用它需要您自担风险。”,所以任何问题或重大错误或错误?

【问题讨论】:

  • magirtopcu,你能解释一下是什么让一个错误对你很重要吗?

标签: java android data-binding


【解决方案1】:

过去几周我一直在使用数据绑定库,考虑到它是第一个版本,它的强大功能令人惊讶。

到目前为止,我发现的唯一错误有一个解决方法。我会在下面解释。

在数据绑定布局文件(现在使用<layout> 标记作为根的布局文件)中使用<include> 标记时,生成的代码会为<include> 标记的父视图组创建一个绑定。

当使用 DataBindingUtil 扩展视图时,应用程序将在尝试解析 ViewGroup 时崩溃。代码生成器和运行时绑定逻辑之间似乎存在不同的行为。

问题示例

这是一个存在上述问题的示例布局。

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

    <data>
    </data>

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">

        <!-- This include causes no issues -->
        <include
            layout="@layout/view_content"/>

        <ScrollView
            android:layout_width="fill_parent"
            android:layout_height="fill_parent">

            <!-- This include however causes the data binding to crash on the ScrollView -->
            <include
                layout="@layout/view_content"/>

        </ScrollView>

    </RelativeLayout>
</layout>

这是包含的布局。

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

    <data>
    </data>

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Test"/>
</layout>

当尝试使用 DataBindingUtil.setContentView 时会发生以下崩溃。

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ScrollView.setTag(java.lang.Object)' on a null object reference

解决方案(解决方法)

我发现的临时解决方法是将虚拟值绑定到&lt;include&gt; 标记的父视图组。这允许数据绑定器在运行时找到 ViewGroup,避免崩溃。

以下是实际修复的示例:

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

    <data>
        <variable
            name="viewModel"
            type="com.example.ViewModel"/>
    </data>

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">

        <!-- This include causes no issues -->
        <include
            layout="@layout/view_content"/>

        <ScrollView
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            bind:visibility="@{viewModel.dummyVisibility}">

            <!-- This include will not cause a problem now that the ScrollView has a value being bound -->
            <include
                layout="@layout/view_content"/>

        </ScrollView>

    </RelativeLayout>
</layout>

这是最基本的视图模型:

package com.example;

import android.databinding.BaseObservable;
import android.databinding.Bindable;
import android.view.View;

public class ViewModel extends BaseObservable {
    @Bindable
    public int getDummyVisibility() {
        // TODO: This is a work around. Currently data binding crashes on certain views if they don't have binding.
        return View.VISIBLE;
    }
}

希望这个问题在未来得到解决,并且不需要这种解决方法!

编辑

我在https://code.google.com/p/android-developer-preview/issues/detail?id=2421 上发现了另一个关于自定义绑定适配器的问题

【讨论】:

  • 您是否在 b.android.com 上报告了此问题?在使用 attachToRoot = true 填充数据绑定器时,我们实际上修复了一个类似的错误。不知道这是不是由它引起的,想确保它是固定的。 (将创建一份内部错误报告,但如果存在,希望链接到公共报告)。
  • 我在发表这篇文章后提出了一个错误报告。这是link。如果是类似的问题,或许可以添加评论而不是提出新问题?
  • 谢谢,我会验证它是否已修复
  • 我遇到了另一个错误,我也在错误跟踪器上提出了这个错误。我用链接编辑了我的原始帖子!
  • 更新了错误,谢谢。
【解决方案2】:

我发现了一个关于 ObservableField 的错误,提交给 here

根据databinding guide,模型类可能包含 ObservableField 属性以保持其属性定义简短。指南中的示例:

private static class User extends BaseObservable {
    public final ObservableField<String> firstName =
       new ObservableField<>();
    public final ObservableField<String> lastName =
       new ObservableField<>();
    public final ObservableInt age = new ObservableInt();
}

通过使用这个类,不会生成类 BR 中的名称属性,也无法编译实现类,因为它们引用了它们。例外:这些属性也在布局 XML 中定义为变量,而在指南的示例布局中不是这种情况:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
   <data>
       <variable name="user" type="com.example.User"/>
   </data>
   <LinearLayout
       android:orientation="vertical"
       android:layout_width="match_parent"
       android:layout_height="match_parent">
       <TextView android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="@{user.firstName}"/>
       <TextView android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="@{user.lastName}"/>
   </LinearLayout>
</layout>

BR.user 已定义; BR.firstName、BR.lastName 和 BR.age 不是。

像这样更改 User 类可以解决问题:

private static class User extends BaseObservable {
    @Bindable
    public final ObservableField<String> firstName =
       new ObservableField<>();
    @Bindable
    public final ObservableField<String> lastName =
       new ObservableField<>();
    @Bindable
    public final ObservableInt age = new ObservableInt();
}

在我看来,当使用 Observable* 类型时,它们的名称应该默认添加到 BR.java 中,而 @Bindable 应该是过时的。

至少应该通过在 ObservableField 示例代码中添加 @Bindable 注释来修复指南。

我花了两天时间来分析和解决这个问题。

【讨论】:

  • 最新版本的Android数据绑定库已经修复了这个bug。
【解决方案3】:

目前不支持@style。例如:

style="@{viewModel.getStyle() ?? @style/default_style}"

如果 getStyle() 返回 null,上面将尝试设置在样式资源中找到的默认样式。不幸的是,这是不可能的,但会为数据绑定 imo 提供非常强大的补充。

【讨论】:

    【解决方案4】:

    当我在 Android 上使用数据绑定库实现 MVVM 模式时,我发现了几个错误。其中一些已经在这里提到过。虽然,我可以添加另一个与事件相关的错误。事件不能包含参数。这意味着数据绑定库在发送事件时没有传输一些额外信息的重要能力。但是,我希望在下一个版本中它会得到修复。在此之前,请在此处查看此问题的解决方案:https://code.google.com/p/android/issues/detail?id=185097

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-16
      • 1970-01-01
      • 2019-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多