Android适配器Base64解码触发空指针异常问题排查修复
异常根因
- 崩溃触发链路清晰:RecyclerView执行
onBindViewHolder绑定列表项时,调用setUserData方法加载用户头像,最终在getUserImage方法执行Base64.decode()时抛出空指针 - 核心问题:部分用户数据的
image字段(存储头像的Base64字符串)值为null,代码未做任何判空处理直接传入解码方法,Base64.decode内部尝试调用null字符串的getBytes()方法,直接触发NPE崩溃 - 额外隐患:即使修复空指针,如果传入的Base64字符串格式非法,
Base64.decode会抛出IllegalArgumentException,BitmapFactory.decodeByteArray也可能返回null,同样会造成显示异常或崩溃
修复方案
1. 核心代码修复
对getUserImage方法增加空判断、异常捕获,头像为空/解码失败时展示预置默认头像,调整后代码如下:
首先修改setUserData方法的调用传参:
void setUserData(User user){ binding.textName.setText(user.name); binding.textEmail.setText(user.email); // 传入上下文用于加载默认头像 binding.imageProfile.setImageBitmap(getUserImage(user.image, binding.getRoot().getContext())); }
替换原有的getUserImage方法:
private Bitmap getUserImage(String encodedImage, Context context){ // 判空:头像字符串为null或空内容时直接返回默认头像 if (encodedImage == null || encodedImage.trim().isEmpty()) { return BitmapFactory.decodeResource(context.getResources(), R.drawable.default_avatar); } try { byte[] bytes = Base64.decode(encodedImage, Base64.DEFAULT); Bitmap avatarBitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); // 兼容解码后Bitmap为null的场景 if (avatarBitmap == null) { return BitmapFactory.decodeResource(context.getResources(), R.drawable.default_avatar); } return avatarBitmap; } catch (IllegalArgumentException e) { // 捕获Base64格式非法导致的解码异常,避免崩溃 e.printStackTrace(); return BitmapFactory.decodeResource(context.getResources(), R.drawable.default_avatar); } }
注意:需要提前在项目res/drawable目录下放置名为
default_avatar.png的默认头像资源,替换成你项目实际的默认头像资源名即可。
2. 可选优化项
- 数据源层校验:从接口/本地数据库获取用户列表数据时,提前对
image字段做兜底,为空时赋值空字符串或者默认头像的Base64值,从源头减少异常数据 - 性能优化:当前头像解码逻辑运行在主线程,列表数据量大时会造成滑动卡顿,建议把解码逻辑移到子线程,或搭配图片加载库实现头像的异步加载、内存缓存,减少主线程阻塞
内容的提问来源于stack exchange,提问作者Factionn
相关产品推荐
相关产品推荐

