assert profilePicUrl判空抛出AssertionError的解决方法
问题根因
- Java的
assert是调试阶段用的内部逻辑校验工具,根本不适合做业务场景的空值判断:它的生效需要运行时开启-ea(启用断言)参数,Android生产环境默认关闭断言,开启时assert语句才会执行,一旦判断条件不成立就直接抛出AssertionError中断程序;关闭时这行代码会被直接跳过,完全起不到防护作用。 - 你这里触发异常的直接原因非常明确:Firebase回调中拿到的
profilePicUrl实际值就是null,profilePicUrl != null的判断不成立,断言直接抛出错误。从Firebase读取数据时,如果对应字段没有存储值,返回null是完全正常的业务边界情况,不属于代码内部逻辑错误,本来就不该用断言处理。
修复方案
- 直接删除
assert profilePicUrl !=null;这行代码,改用显式的常规空判断做逻辑防护,不要依赖断言处理网络/数据库返回的边界值。 - 空判断需要同时覆盖null和空字符串两种场景,避免触发空指针,修正后的业务代码参考:
// 先判空,再执行头像加载 if (profilePicUrl != null && !profilePicUrl.isEmpty()) { Picasso.get().load(profilePicUrl).into(userProfilePic); } else { // 头像地址为空时可以加载本地默认头像,避免控件空白 Picasso.get().load(R.drawable.default_avatar).into(userProfilePic); }
- 从Firebase取数时建议增加节点存在性校验,从源头减少null值出现的概率:
@Override public void onDataChange(@NonNull DataSnapshot snapshot) { // 先判断对应字段节点是否存在、值不为空 if (snapshot.exists() && snapshot.child("profilePicUrl").getValue() != null) { String profilePicUrl = snapshot.child("profilePicUrl").getValue(String.class); if (!profilePicUrl.isEmpty()) { Picasso.get().load(profilePicUrl).into(userProfilePic); return; } } // 所有异常分支统一加载默认头像 Picasso.get().load(R.drawable.default_avatar).into(userProfilePic); }
注意:所有来自外部输入、网络请求、数据库读取的不可信值,都不能用assert做校验。assert仅适合校验代码内部100%确定不会出错的逻辑状态,用来在调试阶段快速发现自身代码的逻辑bug,不能作为生产环境的异常兜底逻辑。
内容的提问来源于stack exchange,提问作者user16705339
相关产品推荐
相关产品推荐

