This article was translated from Japanese by Claude Code.
TL;DR#
When defining variables in XML using the
<data>and<variable>tags in the Data Binding library, actively use primitive types when possibleWhen defining reference type variables, the Data Binding library unboxes them internally
You can also use
safeUnbox()
Details#
The library versions used at the time of writing are:
com.android.support:appcompat-v7: 27.0.1
com.android.databinding:compiler: 3.0.0
Let’s say you’re using the Data Binding library to define variables in XML to change View appearance. Below is a simple XML example where the ProgressBar is visible if isLoading is true, and invisible (View.GONE) otherwise:
<data>
<import type="android.view.View"/>
<variable
name="isLoading"
type="Boolean"
/>
</data>
...
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:visibility="@{isLoading ? View.VISIBLE : View.GONE}"
/>
...At first glance, there’s nothing wrong with this, but when you build the project, you’ll get a warning like the one in the title.
safeUnbox()#
Since Boolean is a reference type, it’s possible for null to be assigned. If null can be assigned, that means a NullPointerException could occur.
If you want to improve this code, there are two solutions.
The first is to specify a type for the variable definition that doesn’t need unboxing. Here, instead of the Boolean type (reference type), you can use the boolean type (primitive type):
<data>
<import
type="android.view.View" />
<variable
name="isLoading"
type="boolean"
/>
</data>
...The second, as mentioned in the warning text:
w: warning: XXX is a boxed field but needs to be un-boxed to execute YYY. This may cause NPE so Data Binding will safely unbox it. You can change the expression and explicitly wrap XXX with safeUnbox() to prevent the warning.
You can use a static method called safeUnbox() that the Data Binding library provides:
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="@{safeUnbox(isLoading) ? View.VISIBLE : View.GONE}"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>This safeUnbox() method is a static method in the DynamicUtil class contained in the android.databinding package:
package android.databinding;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.databinding.BindingConversion;
@javax.annotation.Generated("Android Data Binding")
public class DynamicUtil {
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;
}
}However, in reality, even without explicitly calling this method in XML, the Java source code generated by the Data Binding library calls this method internally to safely unbox (as shown below), so whether you write it or not seems to be fine. (I haven’t investigated this thoroughly, so I’m not fully confident.)
// read android.databinding.DynamicUtil.safeUnbox(isLoading)
androidDatabindingDynamicUtilSafeUnboxIsLoading = android.databinding.DynamicUtil.safeUnbox(isLoading);I learned about DynamicUtil and safeUnbox() for the first time with this, so I’m writing it as a memo! That’s all!
Reference Links#
https://stackoverflow.com/questions/42872201/data-binding-safeunbox-warning