data binding - safeUnbox warning

AndroidData BindingAndroid Gradle-PluginWarningsAndroid Databinding

Android Problem Overview


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"?>

http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">

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

Build is succeed, but warning come out(i past above).

Android Solutions


Solution 1 - Android

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&lt;Integer, boolean&gt;" />

Solution 2 - Android

You can add safeUnbox like this:

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

Solution 3 - Android

> 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.

Solution 4 - Android

Instead of ObservableField<T> you should use special version for the primitives:

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

Solution 5 - Android

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

Solution 6 - Android

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.

Solution 7 - Android

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionIvanView Question on Stackoverflow
Solution 1 - AndroidLeandro D'OnofrioView Answer on Stackoverflow
Solution 2 - Androiddazza5000View Answer on Stackoverflow
Solution 3 - AndroidKhemraj SharmaView Answer on Stackoverflow
Solution 4 - AndroidEugen MartynovView Answer on Stackoverflow
Solution 5 - AndroidJimmyFlashView Answer on Stackoverflow
Solution 6 - AndroidJuan MendezView Answer on Stackoverflow
Solution 7 - AndroidLinhView Answer on Stackoverflow