You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose中用Picasso加载联系人头像遇FileNotFoundException

解决Jetpack Compose中Picasso加载联系人头像URI抛出FileNotFoundException的问题

问题原因

  1. 权限缺失:读取联系人头像需要READ_CONTACTS权限,未申请或未授予时会无法访问content URI。
  2. Target对象被GC回收:匿名内部类实现的Target仅被Picasso以弱引用持有,Compose重组或GC可能在图片加载完成前回收该对象,触发加载失败。
  3. 空状态未处理:代码中直接使用image!!强制非空,加载失败时会引发空指针异常。

解决方案

1. 确认权限配置

在AndroidManifest.xml中添加权限声明:

<uses-permission android:name="android.permission.READ_CONTACTS" />

针对Android 6.0(API 23)及以上版本,需通过ActivityResultContracts.RequestPermission在运行时动态申请权限。

2. 保持Target对象的强引用

用remember存储Target对象,避免被GC回收:

var image by remember { mutableStateOf<ImageBitmap?>(null) }
val uri = viewModel.getAvatarUri().get(neme)?.get()
var drawable by remember { mutableStateOf<Drawable?>(null) }

// 用remember持有Target对象,维持强引用
val target = remember(uri) {
    object : Target {
        override fun onPrepareLoad(placeHolderDrawable: Drawable?) {
            drawable = placeHolderDrawable
        }

        override fun onBitmapFailed(e: Exception?, errorDrawable: Drawable?) {
            e?.printStackTrace()
            drawable = errorDrawable
            image = null // 加载失败时清空image,避免空指针
        }

        override fun onBitmapLoaded(bitmap: Bitmap?, from: Picasso.LoadedFrom?) {
            image = bitmap?.asImageBitmap()
        }
    }
}

DisposableEffect(uri, target) {
    val picasso = Picasso.get()

    uri?.let {
        picasso
            .load(it)
            .placeholder(R.drawable.person)
            .error(R.drawable.person) // 添加错误占位图
            .into(target)
    }

    onDispose {
        image = null
        drawable = null
        picasso.cancelRequest(target)
    }
}

// 处理空状态,避免强制非空
Image(
    bitmap = image ?: ImageBitmap.imageResource(id = R.drawable.person),
    contentDescription = "Avatar",
    modifier = Modifier
        .size(48.dp)
        .background(Color.Gray, CircleShape)
)

3. 额外注意事项

  • 验证viewModel.getAvatarUri()返回的URI有效性,可通过打印uri值确认是否为正确的联系人头像路径。
  • 若问题仍存在,尝试更新Picasso到最新版本,旧版本可能存在Compose兼容性问题。

内容的提问来源于stack exchange,提问作者Slava

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 00:33:28