Привязка данных - предупреждение 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<Integer, Boolean>" />
<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 выше).
Ответы
Ответ 1
У меня было такое же предупреждение, в моем случае изменение объявления переменной из Boolean в тип boolean решает проблему:
From:
<variable
name="readOnly"
type="Boolean" />
To:
<variable
name="readOnly"
type="Boolean" />
Итак, возможно, вы можете попробовать:
<variable
name="selectMap"
type="android.databinding.ObservableMap<Integer, boolean>" />
Ответ 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>
вы должны использовать специальную версию для примитивов:
-
ObservableInt
для int
-
ObservableBoolean
для boolean
-
ObservableFloat
для float
-
ObservableChar
для char
-
ObservableLong
для long
-
ObservableByte
для byte
-
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}"