Подтвердить что ты не робот

Привязка данных - предупреждение safeUnbox

после того, как я обновил версию AS gradle до версии 2.3.0, привязка данных вызывает предупреждение:

Предупреждение: selectMap [index] - поле в боксе, но для выполнения selectMap [index] нужно быть не в коробке? @android: цвет/белый: @android: цвет/прозрачный. Это может вызвать NPE, поэтому Data Binding безопасно распакует его. Вы можете изменить выражение и явно обернуть selectMap [index] с помощью safeUnbox(), чтобы предотвратить предупреждение

selectMap - это ObservableMap, затем я ищу это предупреждение, но получил несколько обсуждений и не исправил его.

Android Studio 2.3.0-alpha1: Databinding + int unboxing вызывает ошибки компиляции

привязка данных - объект данных имеет значение null для 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>

Построение выполнено успешно, но предупреждение появляется (i выше).

4b9b3361

Ответ 1

У меня было такое же предупреждение, в моем случае изменение объявления переменной из Boolean в тип boolean решает проблему:

From:

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

To:

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

Итак, возможно, вы можете попробовать:

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

Ответ 2

Вы можете добавить safeUnbox следующим образом:

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

Ответ 3

w: warning: enabled - это поле в штучной упаковке, но для запуска android: флажок нужно распаковать.

Это предупреждение появляется потому, что разрешенное поле может быть пустым. Если взять Boolean вместо boolean, так Boolean может быть пустым. Так что это предупреждение приходит. Именно это поле может сделать NullPointerException.

---------------- Случай 1 - В одну сторону Binding----------------

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

....

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

Решение 1

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

Решение 2

Измените Boolean на примитивный тип boolean. Чтобы оно никогда не было нулевым, значение по умолчанию boolean равно false.

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

---------------- Случай 2 - двусторонняя Binding---------------- Если у вас есть двусторонняя привязка, то вы не можете использовать safeUnbox() way, потому что safeUnbox() не будет перевернутый

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

....

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

Это не будет работать сейчас.

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

Решение 1

Измените Boolean на примитивный тип boolean. Чтобы оно никогда не было нулевым, значение по умолчанию boolean равно false.

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

Решение 2

Долгий путь - сделать адаптеры с обратной связью для safeUnbox. Смотрите здесь

Что такое метод safeUnbox()?

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;
}

Я объяснил про Boolean, это решение одинаково для Integer, Double, Character и т.д.

Ответ 4

Вместо ObservableField<T> вы должны использовать специальную версию для примитивов:

  1. ObservableInt для int
  2. ObservableBoolean для boolean
  3. ObservableFloat для float
  4. ObservableChar для char
  5. ObservableLong для long
  6. ObservableByte для byte
  7. ObservableShort для short

Ответ 5

У меня было это всплывающее предупреждение, когда я сделал что-то вроде:

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

добавив safeunbox примерно так:

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

убрал предупреждение после перестроения

Ответ 6

В BaseObservable это также может произойти. Мне нужно было обновить тип от Boolean до boolean.

@Bindable
public boolean getAvoidXpressway() {
    return commute.getAvoidXpressway();
}

public void setAvoidXpressway(Boolean avoidXpressway) {
    commute.setAvoidXpressway(avoidXpressway);
    notifyPropertyChanged(BR.avoidXpressway);
}

Если вы привязываетесь к внешнему объекту, как в моем случае, убедитесь, что возвращаемый тип также является логическим; в противном случае предупреждение будет продолжать появляться.

Ответ 7

Это может также появляться, когда вы используете пользовательский BindingAdapter поэтому в моем случае мне нужно было сделать второй аргумент обнуляемым, и предупреждение BindingAdapter.

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

Я не использую Java, но если вы обязательно @Nullable аннотацию @Nullable и выполните нулевое условие.

Ответ 8

Добавьте safeUnbox() в переменную предупреждения, чтобы это предупреждение исчезло, и оно все равно будет работать хорошо

android:alpha="@{alpha != null ? safeUnbox(alpha) : 0.5f}"