after i upgrade AS gradle version to 2.3.0, data binding encounter a warning :
Warning:selectMap[index] is a boxed field but needs to be un-boxed to execute selectMap[index] ? @android:color/white : @android:color/transparent. This may cause NPE so Data Binding will safely unbox it. You can change the expression and explicitly wrap selectMap[index] with safeUnbox() to prevent the warning
selectMap is an ObservableMap, then i search this warning but got just few discussions and did not fix it
Android Studio 2.3.0-alpha1: Databinding + int unboxing causes compile errors
Databinding - data object is null on API 15-18
I follow the way in the links, modify selectMap[index] to safeUnbox(selectMap[index]) but got syntax error.
So anyone know how to fix this warning?
Edit : Here is the xml file code
<?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>
Build is succeed, but warning come out(i past above).
I had the same warning, in my case changing the variable declaration from Boolean type to boolean type solve the problem:
From:
<variable
name="readOnly"
type="Boolean" />
To:
<variable
name="readOnly"
type="boolean" />
So, maybe you can try with:
<variable
name="selectMap"
type="android.databinding.ObservableMap<Integer, boolean>" />
You can add safeUnbox like this:
android:text="@{Double.toString(safeUnbox(product.listPrice))}"
w: warning: enabled is a boxed field but needs to be un-boxed to execute android:checked.
This warning comes because enabled field can be null. If you take Boolean instead of boolean, so Boolean can be null. So this warning comes. That this field can make NullPointerException.
---------------- Case 1 - One Way Binding----------------
<variable
name="enabled"
type="Boolean"/>
....
<Switch
android:checked="@{enabled}"
/>
Solution 1
<Switch
android:checked="@{safeUnbox(fieldName)}"
/>
Solution 2
Change Boolean to primitive type boolean. So that it never be null, default value of boolean is false.
<variable
name="enabled"
type="boolean"/>
---------------- Case 2 - Two-Way Binding----------------
When you have two-way binding, then you can not use safeUnbox() way, because safeUnbox() will not be inverted.
<variable
name="enabled"
type="Boolean"/>
....
<Switch
android:checked="@={enabled}"
/>
This will not work now.
<Switch
android:checked="@{safeUnbox(fieldName)}"
/>
Solution 1
Change Boolean to primitive type boolean. So that it never be null, default value of boolean is false.
<variable
name="enabled"
type="boolean"/>
Solution 2
A long way is to make inverse binding adapters for safeUnbox. See here.
What is safeUnbox() method?
safeUnbox() just check null value and return non-null value. You can see below methods which are defined in Data binding library.
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.
Instead of ObservableField<T> you should use special version for the primitives:
ObservableIntfor theintObservableBooleanfor thebooleanObservableFloatfor thefloatObservableCharfor thecharObservableLongfor thelongObservableBytefor thebyteObservableShortfor theshort
I had this warning popup when i did something like :
android:visibility="@{viewmodel.isLoading ? View.INVISIBLE : View.VISIBLE}"
adding safeunbox like so :
android:visibility="@{safeUnbox(viewmodel.isLoading) ? View.INVISIBLE : View.VISIBLE}"
removed the warning after rebuild
This can appear as well whenever you are using a custom BindingAdapter so in my case I needed to make the second argument as nullable, and the warning went away.
@BindingAdapter("xyz")
fun xyzAdapter(view: View, value: Int?) {
value?.let {
//TODO
}
}
I am not using Java, but if you are make sure to include @Nullable annotation, and do a null condition.
Add the safeUnbox() to the warning variable will make this warning gone and it will still work well
android:alpha="@{alpha != null ? safeUnbox(alpha) : 0.5f}"
来源:https://stackoverflow.com/questions/42872201/data-binding-safeunbox-warning