Glide加载图片时,报You must not call setTag() on a view Glide is targeting 的问题

为了在程序中避免重复加载同一张图片,我们在加载图片时一般会这样

1
2
3
4
5
6
string imageUrl;

if (!imageUrl.equals(imageView.getTag())) {
glide.load(imageUrl).into(imageView);
imageView.setTag(imageUrl);
}

然后如果图片正在加载的时候,我们突然退出当前页面,系统会报异常

1
java.lang.IllegalArgumentException: You must not call setTag() on a view Glide is targeting

经过跟踪Glide的源码,发现

1
2
3
4
5
6
7
8
9
10
11
12
public Request getRequest() {
Object tag = getTag();
Request request =null;
if (tag !=null) {
if (tag instanceof Request) {
request = (Request) tag;
} else {
throw new IllegalArgumentException("You must not call setTag() on a view Glide is targeting");
}
}
return request;
}

这段代码的意思是,当Glide通过getRequest()方法获取request时,会强制将tag强转为request类型,如果tag不属于request类型就会报以上的异常信息

同文件下也可以找到下面这个方法,也说明是将request设置到了tag中

1
2
3
4
@Override
public void setRequest(@Nullable Request request) {
setTag(request);
}

通过搜索我们通常找到的解决方法是在glide into之前将tag设置为null,然后再into之后再将tag设置为对应的imageUrl。如下面的代码

1
2
3
4
5
6
7
string imageUrl;

if (!imageUrl.equals(imageView.getTag())) {
imageView.setTag(null);
glide.load(imageUrl).into(imageView);
imageView.setTag(imageUrl);
}

一般情况下该问题即可解决,但项目中,当在设置页面退出登录时,还是会报以上的异常,所以这种方式只是治标,并没有根本上解决问题

后来又发现以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
private void setTag(@Nullable Object tag) {
if (tagId ==null) {
isTagUsedAtLeastOnce =true;
view.setTag(tag);
} else {
view.setTag(tagId, tag);
}
}

@Nullable
private ObjectgetTag() {
if (tagId ==null) {
return view.getTag();
} else {
return view.getTag(tagId);
}
}

public static void setTagId(int tagId) {
if (ViewTarget.tagId !=null || isTagUsedAtLeastOnce) {
throw new IllegalArgumentException("You cannot set the tag id more than once or change" + " the tag id after the first request has been made");
}
ViewTarget.tagId = tagId;
}

通过上述代码我们可以通过tagId来设置request的tag,这样在外界设置tag的时候就不会出现冲突

首先我们需要在资源目录下 新建一个ids的资源文件,内容为

1
2
3
<resources>
<item name="glideIndexTag" type="id"/>
</resources>

然后我们在ApplicationonCreate()方法中

1
ViewTarget.setTagId(R.id.glideIndexTag);

或在AppGlideModule初始化加载中配置

1
2
3
4
5
6
7
@GlideModule
public final class MyAppGlideModule extends AppGlideModule {
@Override
public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {
ViewTarget.setTagId(R.id.glideIndexTag);
}
}

这样我们即可在其他地方随意的使用setTag()

Powered by AppBlog.CN     浙ICP备14037229号

Copyright © 2012 - 2020 APP开发技术博客 All Rights Reserved.

访客数 : | 访问量 :