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

Picasso加载URI至ImageView后,获取Drawable返回null的问题

解决Picasso加载后立即获取Drawable为null的问题

嘿,这个坑我刚踩过没多久!你现在的问题核心在于Picasso的图片加载是异步的——你调用Picasso.get().load(a).into(tempimg)之后,立刻去拿tempimg.getDrawable(),这时候图片还在后台下载/读取缓存呢,ImageView根本还没拿到Drawable,所以自然返回null啦。

为什么会这样?

Picasso为了不阻塞主线程,所有的图片加载操作都是在后台线程完成的,into()方法只是把加载任务提交出去,并不会等加载完成再返回。你写的代码是同步执行的,刚提交任务就去取结果,肯定拿不到嘛。

正确的解决方法

推荐用Picasso提供的Callback回调,等图片加载成功后再去获取Drawable,这样就不会有null的问题了:

val tempimg = ImageView(this)
val imageUrl = pageURIFd + page
Picasso.get().load(imageUrl).into(tempimg, object : Callback {
    override fun onSuccess() {
        // 这里图片已经稳稳加载完成了,放心拿Drawable
        val drawable = tempimg.drawable as BitmapDrawable
        bitmaps.add(drawable)
        // 如果后续要更新UI,这里本来就在主线程,直接操作就行
    }

    override fun onError(e: Exception?) {
        // 别忘了处理加载失败的情况,比如打印错误或者给用户提示
        e?.printStackTrace()
        // 也可以在这里加个默认占位图进去
    }
})

如果你更想直接拿到Bitmap(而不是通过ImageView中转),也可以用同步获取的方式,但一定要放在后台线程,不然会导致主线程阻塞ANR:

// 用Kotlin协程的例子,你也可以用Thread(不推荐AsyncTask)
CoroutineScope(Dispatchers.IO).launch {
    try {
        val bitmap = Picasso.get().load(pageURIFd + page).get()
        val drawable = BitmapDrawable(resources, bitmap)
        // 切换回主线程更新集合(如果bitmaps是给UI用的)
        withContext(Dispatchers.Main) {
            bitmaps.add(drawable)
        }
    } catch (e: Exception) {
        e.printStackTrace()
    }
}

小提醒

  • 优先用第一种回调的方式,这是Picasso设计的标准用法,更符合Android的异步规范。
  • 强制类型转换as BitmapDrawable的时候最好加个安全判断,比如tempimg.drawable as? BitmapDrawable,避免类型不对导致崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:27:00