编译警告:使用DataBinding 时,如果你在xml中使用了基本数据类型,可能会出现如下编译警告:
This may cause NPE so Data Binding will safely unbox it.
You can change the expression and explicitly wr ready with safeUnbox() to prevent the warning
大致意思是:
这可能会导致空指针,所以Data Binding 将安全的拆箱,你可以显示的调用`safeUnbox()`来消除这个警告.
警告原因:
就是java的自动拆箱,比如如下代码,直接调用outboolean()
编译会报错,但是调用outBoolean()
却可以。因为基本数据类型是不可以传null
的,引用类型可以。在outBoolean()
中调用outboolean()
编译并不会报错,但是运行时会NPE
。
@Test
public void addition_isCorrect() throws Exception {
//error
outboolean(null);
//cause NPE
outBoolean(null);
}
void outBoolean(Boolean b){
outboolean(b);
}
void outboolean(boolean b){
System.out.println(b);
}
解决方法:
方法一:
如果你没有强迫症,可以直接忽略这个警告。警告里也说了Data Binding 将安全的拆箱
,所以不处理并不会导致任何问题,因为DataBinding已经帮我们安全的拆箱了。
以Boolean
为例,看看Data Binding 是如何安全拆箱的://可能为空 boolean mInEdit; //执行绑定 protected void executeBindings() { //创建一个变量(名字好长..) boolean androidDatabindingDynamicUtilSafeUnboxInEdit = false; //自动生成的ViewDataBinding 就是这样写的,虽然并没什么用 //(inEdit这个局部变量在这个就在下面的方法里用到了,为啥不直接用mInEdit?) java.lang.Boolean inEdit = mInEdit; //安全拆箱 androidDatabindingDynamicUtilSafeUnboxInEdit = android.databinding.DynamicUtil.safeUnbox(inEdit); //下面的代码里面只使用 androidDatabindingDynamicUtilSafeUnboxInEdit ,不再使用mInEdit和inEdit; // 所以肯定不会空指针了 }
这个是safeUnbox方法源码:
/** @hide */ protected static boolean safeUnbox(java.lang.Boolean boxed) { return boxed == null ? false : (boolean)boxed; }
方法二
按警告说的改代码喽,就加一个safeUnbox()
,不用import
,自动生成的**DataBinding
的父类ViewDataBinding
中有这个方法。
修改前:<layout > <data> <import type="android.view.View" /> <variable name="inEdit" type="Boolean" /> </data> <ImageView ... android:visibility="@{inEdit?View.GONE:View.VISIBLE}" /> </layout>
修改后:
<layout > <data> <import type="android.view.View" /> <variable name="inEdit" type="Boolean" /> </data> <ImageView ... android:visibility="@{safeUnbox(inEdit)?View.GONE:View.VISIBLE}" /> </layout>
然后就没有警告了……