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

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

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>

然后我们在ApplicationonCreate()方法中

ViewTarget.setTagId(R.id.glideIndexTag);

或在AppGlideModule初始化加载中配置

@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()

版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/02/26/glide-load-images-report-you-must-not-call-settag-on-a-view-glide-is-targeting/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
海报
Glide加载图片时,报You must not call setTag() on a view Glide is targeting 的问题
为了在程序中避免重复加载同一张图片,我们在加载图片时一般会这样 string imageUrl; if (!imageUrl.equals(imageView.getTag())) { glide.load(imageUrl……
<<上一篇
下一篇>>
文章目录
关闭
目 录