数据绑定 - safeUnbox警告

问题描述 投票:38回答:7

将AS gradle版本升级到2.3.0后,数据绑定会遇到警告:

警告:selectMap [index]是一个盒装字段但需要取消装箱才能执行selectMap [index]? @android:颜色/白色:@android:颜色/透明。这可能会导致NPE,因此数据绑定将安全地取消它。您可以更改表达式并使用safeUnbox()显式地包装selectMap [index]以防止出现警告

selectMap是一个ObservableMap,然后我搜索这个警告,但只进行了一些讨论而没有修复它

Android Studio 2.3.0-alpha1: Databinding + int unboxing causes compile errors

Databinding - data object is null on API 15-18

我按照链接的方式,将selectMap[index]修改为safeUnbox(selectMap[index]),但语法错误。

所以任何人都知道如何修复此警告?


编辑:这是xml文件代码

<?xml version="1.0" encoding="utf-8"?>

<data class="SupportCountryViewHolderBinding">

    <variable
        name="viewModel"
        type="com.goodarc.care_about.activity.account.support_country.SupportCountryHolderViewModel" />

    <variable
        name="dataSource"
        type="com.goodarc.care_about.module.assets_file.SupportCountry" />

    <variable
        name="selectMap"
        type="android.databinding.ObservableMap&lt;Integer, Boolean&gt;" />

    <variable
        name="index"
        type="int" />
</data>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@{selectMap[index] ? @android:color/white : @android:color/transparent}"
    android:onClick="@{(v) -> viewModel.onItemSelectListener(selectMap, index)}"
    android:orientation="vertical"
    android:padding="20dp">

    <TextView
        style="@style/TitleLabel2"
        android:layout_gravity="center_vertical|start"
        android:text="@{dataSource.display}"
        android:textColor="@{selectMap[index] ? @android:color/black : @android:color/white}"
        tools:text="Taiwan (+886)" />
</LinearLayout>

构建成功,但警告出来(我在上面)。

android data-binding android-gradle warnings android-databinding
7个回答
34
投票

我有同样的警告,在我的情况下,将变量声明从布尔类型更改为布尔类型解决问题:

从:

<variable
        name="readOnly"
        type="Boolean" />

至:

<variable
        name="readOnly"
        type="boolean" />

所以,也许你可以尝试:

<variable
    name="selectMap"
    type="android.databinding.ObservableMap&lt;Integer, boolean&gt;" />

23
投票

您可以像这样添加safeUnbox:

android:text="@{Double.toString(safeUnbox(product.listPrice))}"

10
投票

w:warning:enabled是一个盒装字段但需要取消装箱才能执行android:checked。

出现此警告是因为enabled字段可以为null。如果你取Boolean而不是boolean,那么Boolean可以为null。所以这个警告来了。这个领域可以使NullPointerException

----------------案例1 - 单向绑定----------------

<variable
    name="enabled"
    type="Boolean"/>

....

<Switch
    android:checked="@{enabled}"
    />

Solution 1

<Switch
    android:checked="@{safeUnbox(fieldName)}"
    />

Solution 2

Boolean更改为原始类型boolean。所以它永远不会为空,default valuebooleanfalse

<variable
    name="enabled"
    type="boolean"/>

----------------案例2 - 双向绑定----------------当你有双向绑定时,你可以不使用safeUnbox()的方式,因为safeUnbox() will not be inverted

<variable
    name="enabled"
    type="Boolean"/>

....

<Switch
    android:checked="@={enabled}"
    />

这现在不起作用。

<Switch
    android:checked="@{safeUnbox(fieldName)}"
    />

Solution 1

Boolean更改为原始类型boolean。因此它永远不会为空,default valueboolean是假的。

<variable
    name="enabled"
    type="boolean"/>

Solution 2

很长的方法是为safeUnbox制作反向绑定适配器。 See here

What is safeUnbox() method?

safeUnbox()只检查空值并返回非空值。您可以在下面看到数据绑定库中定义的方法。

public static int safeUnbox(java.lang.Integer boxed) {
    return boxed == null ? 0 : (int)boxed;
}
public static long safeUnbox(java.lang.Long boxed) {
    return boxed == null ? 0L : (long)boxed;
}
public static short safeUnbox(java.lang.Short boxed) {
    return boxed == null ? 0 : (short)boxed;
}
public static byte safeUnbox(java.lang.Byte boxed) {
    return boxed == null ? 0 : (byte)boxed;
}
public static char safeUnbox(java.lang.Character boxed) {
    return boxed == null ? '\u0000' : (char)boxed;
}
public static double safeUnbox(java.lang.Double boxed) {
    return boxed == null ? 0.0 : (double)boxed;
}
public static float safeUnbox(java.lang.Float boxed) {
    return boxed == null ? 0f : (float)boxed;
}
public static boolean safeUnbox(java.lang.Boolean boxed) {
    return boxed == null ? false : (boolean)boxed;
}

I explained about Boolean, this solution is same for Integer, Double, Character etc.


7
投票

而不是ObservableField<T>你应该使用特殊版本的基元:

  1. ObservableIntint
  2. ObservableBooleanboolean
  3. ObservableFloatfloat
  4. ObservableCharchar
  5. ObservableLonglong
  6. ObservableBytebyte
  7. ObservableShortshort

5
投票

当我做了类似的事情时,我有这个警告弹出窗口:

 android:visibility="@{viewmodel.isLoading ? View.INVISIBLE : View.VISIBLE}"

像这样添加safeunbox:

 android:visibility="@{safeUnbox(viewmodel.isLoading) ? View.INVISIBLE : View.VISIBLE}"

重建后删除警告


0
投票

当你使用自定义BindingAdapter时,这也可以出现,所以在我的情况下,我需要将第二个参数设置为可空,并且警告消失了。

@BindingAdapter("xyz")
fun xyzAdapter(view: View, value: Int?) {
  value?.let {
    //TODO
  }
}

我没有使用Java,但是如果你确保包含@Nullable注释,并且执行null条件。


-1
投票

safeUnbox()添加到警告变量将使此警告消失,它仍然可以正常工作

android:alpha="@{alpha != null ? safeUnbox(alpha) : 0.5f}"
© www.soinside.com 2019 - 2024. All rights reserved.