为了在程序中避免重复加载同一张图片,我们在加载是一般会这样
string imageUrl;
if(!imageUrl.equals(imageView.getTag())){
glide.load(imageUrl).into(imageView);
imageView.setTag(imageUrl);
}
然后如果图片正在加载的时候,我们突然退出当前页面,系统就会报java.lang.IllegalArgumentException: You must not call setTag() on a view Glide is targeting 异常。
这是什么原因呢??经过跟踪glide的源码,我发现这样一个地方
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中。
@Override
public void setRequest(@Nullable Request request) {
setTag(request);
}
通过百度我们通常找到的方法是在glide into之前将tag设置为null,然后再into之后再将tag设置为对应的imageUrl。如下面的代码
string imageUrl;
if(!imageUrl.equals(imageView.getTag())){
imageView.setTag(null);
glide.load(imageUrl).into(imageView);
imageView.setTag(imageUrl);
}
一般情况下 这个问题就解决了,但在我的项目中,当我在设置页面退出登录时,还是会报以上的异常,
所以这种方式只是治标,并没有根本上解决问题;
后来我又发现以下代码:
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的资源文件,内容为
<resources>
<item name="glideIndexTag" type="id"/>
</resources>
然后我们在baseApplication的onCreate()方法中
ViewTarget.setTagId(R.id.glideIndexTag);
这样我们就可以在其他的地方随意的使用setTag()了。
网友评论