Glide获取Drawable为null:构造方法中如何等待Drawable加载完成?
嘿,我来帮你拆解下这个问题~首先咱得搞明白为啥构造方法里拿不到Drawable:Glide加载图片是异步操作,它不会阻塞主线程去等图片下载/解码完成,而自定义View的构造方法是在View被创建时同步执行的,这时候图片还在加载路上呢,自然会拿到null,也就触发了NullPointerException(就是你看到的调用getIntrinsicWidth()时的报错)。
你提到监听器里能正常工作,这完全说得通——因为Glide的回调(比如onResourceReady)就是专门等图片加载完成后才会触发的,这时候Drawable已经准备就绪了。
为什么不能在构造方法里“等待”?
直接在构造方法里做阻塞等待(比如用Thread.sleep()或者CountDownLatch)是绝对不可行的!这会卡住主线程,导致界面完全无响应,轻则用户体验爆炸,重则触发ANR(应用无响应)弹窗,这是Android开发的红线,千万别碰。
正确的解决方案:把逻辑移到回调里,或者给View加触发方法
咱换个思路,不是让构造方法等图片,而是让需要用到Drawable的逻辑在图片加载完成后再执行,具体可以这么做:
1. 给自定义View添加一个专门的方法处理Drawable
把原来构造方法里依赖Drawable的逻辑,抽成一个独立的方法,比如:
public class MyCustomView extends View { // 构造方法只做基础初始化,别碰Drawable相关逻辑 public MyCustomView(Context context) { super(context); initBasic(); // 比如初始化画笔、背景这些不依赖图片的内容 } // 专门用来处理加载完成的Drawable public void setupWithLoadedDrawable(Drawable drawable) { if (drawable == null) return; // 这里放你原来在构造方法里需要用Drawable的逻辑 int width = drawable.getIntrinsicWidth(); int height = drawable.getIntrinsicHeight(); // ... 你的其他操作 } private void initBasic() { // 基础初始化逻辑 } }
2. 在Glide的回调中调用这个方法
用Glide加载图片时,通过CustomTarget来监听加载完成事件,拿到Drawable后传给自定义View:
// 假设你在Activity/Fragment里加载图片 MyCustomView customView = findViewById(R.id.my_custom_view); Glide.with(this) .load("你的图片URL/本地路径") .into(new CustomTarget<Drawable>() { @Override public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) { // 图片加载完成,调用自定义View的方法处理 customView.setupWithLoadedDrawable(resource); } @Override public void onLoadCleared(@Nullable Drawable placeholder) { // 可选:处理图片被清除的情况 } });
额外小提示
如果你的自定义View需要直接显示这个Drawable,也可以在setupWithLoadedDrawable里调用setBackground(resource)或者自己绘制这个Drawable,完全没问题。
总结一下:核心就是利用Glide的异步回调机制,让依赖Drawable的逻辑“延后执行”,而不是在构造方法里硬等——毕竟异步加载的本质就是“先干活,干完了通知你”,咱得顺着这个逻辑来~
内容的提问来源于stack exchange,提问作者Darren

