Android调用BitmapDrawable.getBitmap()空对象引用报错如何解决?
崩溃根因
- 报错触发在
setBackgroundImage()方法的Bitmap bitmap = ((BitmapDrawable)imageView.getDrawable()).getBitmap();行,原因是调用getBitmap()的BitmapDrawable对象为空。 - 常见触发场景:
- 图片未完成加载时用户点击了设置按钮:此时ImageView的drawable是布局配置的
@color/colorPrimary,属于ColorDrawable类型,强转为BitmapDrawable会失败返回空,调用方法就触发空指针。 - Glide加载图片失败:如传入的图片链接无效、无网络、资源不存在,此时ImageView的drawable为空或非BitmapDrawable类型,也会触发崩溃。
- 图片未完成加载时用户点击了设置按钮:此时ImageView的drawable是布局配置的
修复方案
- 给
setBackgroundImage()方法加安全校验:先判断drawable是否为空、是否为BitmapDrawable类型,避免非法强转和空调用。 - 监听Glide加载状态:加载完成前禁用设置按钮,防止用户提前点击;加载失败时给出明确提示。
- 补充权限校验:设置壁纸需要申请
SET_WALLPAPER权限,需在AndroidManifest.xml中添加对应声明。
修改后业务代码
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_view); imageView = findViewById(R.id.viewImage); setBack = findViewById(R.id.setBackground); // 初始禁用按钮,防止加载完成前误点 setBack.setEnabled(false); String imgUrl = getIntent().getStringExtra("images"); Glide.with(this) .load(imgUrl) .listener(new RequestListener<Drawable>() { @Override public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) { Toast.makeText(ViewActivity.this, "图片加载失败,请检查链接或网络后重试", Toast.LENGTH_SHORT).show(); return false; } @Override public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) { // 加载成功后启用设置按钮 setBack.setEnabled(true); return false; } }) .into(imageView); setBack.setOnClickListener(v -> setBackgroundImage()); } private void setBackgroundImage() { Drawable drawable = imageView.getDrawable(); // 安全校验 if (drawable == null || !(drawable instanceof BitmapDrawable)) { Toast.makeText(getApplicationContext(), "图片未加载完成,请稍后再试", Toast.LENGTH_SHORT).show(); return; } Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap(); WallpaperManager manager = WallpaperManager.getInstance(getApplicationContext()); try { manager.setBitmap(bitmap); Toast.makeText(getApplicationContext(), "设置壁纸成功", Toast.LENGTH_SHORT).show(); } catch (IOException e) { Toast.makeText(this, "设置壁纸失败,请重试", Toast.LENGTH_SHORT).show(); e.printStackTrace(); } }
可选优化
如果需要保留加载前的占位图显示,可将布局中ImageView的android:src="@color/colorPrimary"替换为Bitmap类型的占位drawable,避免ColorDrawable的强转问题,不替换也不影响功能,代码中已做类型兼容。
内容的提问来源于stack exchange,提问作者Shubham Prashar
相关产品推荐
相关产品推荐

