一.RecycleView或者ViewPager使用glide的SimpleTarget加载图片的时候,滑动时会很卡,而且第一个和最后一个item初始化失败
背景:加载图片之后需要获取图片的宽高,使用SimpleTarget获取图片的宽高之后,就会出现以上的问题
经过分析,之所以会出现上面的问题,主要还是由于RecyclerView的复用机制导致的。当我滑动的时候,顶部的View是复用被移出列表的itemView,但是这些被复用的itemView可能还在加载之前的数据,可是这些itemView还要加载当前位置上需要加载的数据,这就导致glide一直在加载,没有释放,用CustomViewTarget替换SimpleTarget就可解决
Glide.with(holder.itemView.getContext()).asBitmap().load(getItem(position).getUrl())
.skipMemoryCache(true)
.apply(RequestOptions.placeholderOf(R.drawable.ic_is_shooting_large).error(R.drawable.ic_is_shooting_large))
.into(new ImageViewTarget(holder.pagerPhoto));
static class ImageViewTarget extends CustomViewTarget<PhotoView, Bitmap> {
public ImageViewTarget(@NonNull PhotoView ivPic) {
super(ivPic);
}
@Override
protected void onResourceCleared(@Nullable Drawable placeholder) {
Log.i(TAG, "onResourceCleared: ");
}
@Override
public void onLoadFailed(@Nullable Drawable errorDrawable) {
Log.i(TAG, "onLoadFailed: ");
this.view.setImageDrawable(errorDrawable);
}
@Override
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
//自行设置Drawable
this.view.setImageBitmap(resource);
}
}
要加上skipMemoryCache,否则会OOM
二.class f.f.a.q.r.d.b0$a: Mark has been invalidated, pos: 3254807 markLimit: 5242880
2023-05-25 08:41:20.188 25095-25095/? W/Glide: Load failed for xx with size [1080x2280]
class f.f.a.q.p.q: Failed to load resource
There was 1 root cause:
f.f.a.q.r.d.b0$a(Mark has been invalidated, pos: 3254807 markLimit: 5242880)
call GlideException#logRootCauses(String) for more detail
Cause (1 of 1): class f.f.a.q.p.q: Failed LoadPath{c->Bitmap->Bitmap}, REMOTE
There was 1 root cause:
f.f.a.q.r.d.b0$a(Mark has been invalidated, pos: 3254807 markLimit: 5242880)
call GlideException#logRootCauses(String) for more detail
Cause (1 of 1): class f.f.a.q.p.q: Failed DecodePath{c->Bitmap->Bitmap}
There was 1 root cause:
f.f.a.q.r.d.b0$a(Mark has been invalidated, pos: 3254807 markLimit: 5242880)
call GlideException#logRootCauses(String) for more detail
Cause (1 of 1): class f.f.a.q.r.d.b0$a: Mark has been invalidated, pos: 3254807 markLimit: 5242880
2023-05-25 08:41:20.188 25095-25095/? I/Glide: Root cause (1 of 1)
f.f.a.q.r.d.b0$a: Mark has been invalidated, pos: 3254807 markLimit: 5242880
at f.f.a.q.r.d.b0.reset(RecyclableBufferedInputStream.java:5)
at f.f.a.q.f$d.a(ImageHeaderParserUtils.java:2)
at f.f.a.q.f.c(ImageHeaderParserUtils.java:3)
at f.f.a.q.f.b(ImageHeaderParserUtils.java:4)
at f.f.a.q.r.d.x$a.a(ImageReader.java:3)
at f.f.a.q.r.d.q.h(Downsampler.java:6)
at f.f.a.q.r.d.q.e(Downsampler.java:10)
at f.f.a.q.r.d.q.g(Downsampler.java:1)
at f.f.a.q.r.d.f0.c(StreamBitmapDecoder.java:7)
at f.f.a.q.r.d.f0.b(StreamBitmapDecoder.java:1)
at f.f.a.q.p.i.c(DecodePath.java:6)
at f.f.a.q.p.i.b(DecodePath.java:2)
at f.f.a.q.p.i.a(DecodePath.java:1)
at f.f.a.q.p.t.c(LoadPath.java:3)
at f.f.a.q.p.t.b(LoadPath.java:2)
at f.f.a.q.p.h.z(DecodeJob.java:3)
at f.f.a.q.p.h.h(DecodeJob.java:2)
at f.f.a.q.p.h.g(DecodeJob.java:3)
at f.f.a.q.p.h.i(DecodeJob.java:3)
at f.f.a.q.p.h.d(DecodeJob.java:11)
at f.f.a.q.p.z.h(SourceGenerator.java:7)
at f.f.a.q.p.z$a.e(SourceGenerator.java:2)
at f.f.a.q.q.q$a.e(MultiModelLoader.java:1)
at f.f.a.q.o.j.d(HttpUrlFetcher.java:3)
at f.f.a.q.q.q$a.d(MultiModelLoader.java:4)
at f.f.a.q.p.z.j(SourceGenerator.java:3)
at f.f.a.q.p.z.b(SourceGenerator.java:12)
at f.f.a.q.p.h.y(DecodeJob.java:4)
at f.f.a.q.p.h.A(DecodeJob.java:7)
at f.f.a.q.p.h.run(DecodeJob.java:7)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
at f.f.a.q.p.c0.a$b$a.run(GlideExecutor.java:6)
出现以上异常的代码:
Glide.with(holder.itemView.getContext()).asBitmap().load(getItem(position).getUrl())
.skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.apply(RequestOptions.placeholderOf(R.drawable.ic_is_shooting_large).error(R.drawable.ic_is_shooting_large))
.into(new ImageViewTarget(holder.pagerPhoto));
在网上查找了很多资料,确定是由于diskCacheStrategy造成的,参考资料: