data binding - safeUnbox warning

31,201

Solution 1

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

You can add safeUnbox like this:

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

Solution 3

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

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

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

Share:
31,201
Ivan
Author by

Ivan

Updated on February 20, 2020

Comments

  • Ivan
    Ivan over 4 years

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

  • Admin
    Admin about 7 years
    Did you have the same problem with Strings? In my case was only with Boolean
  • Shubham AgaRwal
    Shubham AgaRwal about 7 years
    Sorry there was no problem with String it was something else AFAIR
  • illusionJJ
    illusionJJ almost 7 years
    I think safeUnbox is simple solution. public static boolean safeUnbox(java.lang.Boolean boxed) { return boxed == null ? false : (boolean) boxed; } in android.databinding.DynamicUtil
  • Piotr Aleksander Chmielowski
    Piotr Aleksander Chmielowski over 5 years
    I'd not recommend using safeUnbox method. If a developer is using a nullable Boolean type and is setting it to null, probably he or she doesn not mean false. Use non nullable boolean type if you don't need nullability, handle null explicitly with custom adapter or - if you're using Boolean but don't expect null in the current state - just let the application throw NPE to warn you that there is a bug to be fixed.