Android获取音乐专辑封面时decodeResource加载矢量图报NullPointerException
报错原因
你遇到的空指针是因为 BitmapFactory 仅支持解析png、jpg等格式的位图资源,无法直接加载svg转换得到的xml格式矢量Drawable,调用BitmapFactory.decodeResource()加载矢量资源时会返回null,而你定义的方法返回值是不可空的Bitmap类型,就触发了空指针校验异常。
解决方案
替换最后返回默认图的逻辑,改用兼容矢量Drawable的方式将其转换为Bitmap,具体实现如下:
- 新增矢量Drawable转Bitmap的工具方法
private fun getBitmapFromVectorDrawable(context: Context, drawableId: Int): Bitmap { val drawable = ContextCompat.getDrawable(context, drawableId) ?: throw IllegalArgumentException("无法找到指定Drawable资源") // 防止矢量图宽高未声明的异常,最小取1px val width = drawable.intrinsicWidth.coerceAtLeast(1) val height = drawable.intrinsicHeight.coerceAtLeast(1) val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888) val canvas = Canvas(bitmap) drawable.setBounds(0, 0, canvas.width, canvas.height) drawable.draw(canvas) return bitmap }
- 修改
getAlbumArtBitmap方法的返回逻辑,同时建议扩大异常捕获范围,避免遗漏其他未知异常导致崩溃:
fun getAlbumArtBitmap(context: Context, albumId: Long): Bitmap { try { return when { Build.VERSION.SDK_INT >= Build.VERSION_CODES.P -> { val source = ImageDecoder.createSource( context.contentResolver, getAlbumArtUri(albumId) ) ImageDecoder.decodeBitmap(source) } else -> MediaStore.Images.Media.getBitmap( context.contentResolver, getAlbumArtUri(albumId) ) } } catch (e: Exception) { Timber.e(e) } // 替换原来的BitmapFactory调用 return getBitmapFromVectorDrawable(context, R.drawable.ic_logo) }
额外注意事项
- 确认你的矢量Drawable资源存放在通用
drawable目录或者drawable-anydpi目录下,不要仅放在特定dpi的资源目录,避免部分机型匹配不到资源 - 若你的项目使用的AppCompat版本低于1.1.0,需要在模块级
build.gradle的defaultConfig块中添加配置vectorDrawables.useSupportLibrary = true开启矢量图兼容支持
内容的提问来源于stack exchange,提问作者ibramazin
相关产品推荐
相关产品推荐

