Glide加载SVG国旗图片失败,请求技术解决方法
解决Glide加载SVG图片失败的问题
问题原因
Glide默认不具备SVG格式的解码能力,直接加载SVG URL时无法解析矢量图数据,因此出现加载失败的报错。另外你代码里额外开启线程再切换回UI线程调用Glide是完全多余的——Glide内部已经封装了异步加载逻辑,这种操作反而可能引发不必要的问题。
解决步骤
1. 添加依赖
在Module级别的build.gradle文件中添加以下依赖:
// Glide核心库 implementation 'com.github.bumptech.glide:glide:4.16.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.16.0' // AndroidSVG库,用于解析SVG implementation 'com.caverock:androidsvg-aar:1.4'
2. 实现SVG解码与转码逻辑
创建三个类来让Glide支持SVG:
SVG解码器
import android.graphics.drawable.PictureDrawable; import com.bumptech.glide.load.Options; import com.bumptech.glide.load.ResourceDecoder; import com.bumptech.glide.load.engine.Resource; import com.bumptech.glide.load.resource.SimpleResource; import com.caverock.androidsvg.SVG; import java.io.IOException; import java.io.InputStream; public class SvgDecoder implements ResourceDecoder<InputStream, SVG> { @Override public boolean handles(InputStream source, Options options) { return true; } @Override public Resource<SVG> decode(InputStream source, int width, int height, Options options) throws IOException { SVG svg = SVG.getFromInputStream(source); return new SimpleResource<>(svg); } }
SVG转码器
import android.graphics.Picture; import android.graphics.drawable.PictureDrawable; import com.bumptech.glide.load.Options; import com.bumptech.glide.load.resource.transcode.ResourceTranscoder; import com.bumptech.glide.load.engine.Resource; import com.bumptech.glide.load.resource.SimpleResource; import com.caverock.androidsvg.SVG; public class SvgDrawableTranscoder implements ResourceTranscoder<SVG, PictureDrawable> { @Override public Resource<PictureDrawable> transcode(Resource<SVG> toTranscode, Options options) { SVG svg = toTranscode.get(); Picture picture = svg.renderToPicture(); PictureDrawable drawable = new PictureDrawable(picture); return new SimpleResource<>(drawable); } }
Glide注册模块
import android.content.Context; import com.bumptech.glide.Glide; import com.bumptech.glide.Registry; import com.bumptech.glide.annotation.GlideModule; import com.bumptech.glide.module.AppGlideModule; import com.caverock.androidsvg.SVG; import android.graphics.drawable.PictureDrawable; import java.io.InputStream; @GlideModule public class SvgGlideModule extends AppGlideModule { @Override public void registerComponents(Context context, Glide glide, Registry registry) { registry.register(SVG.class, PictureDrawable.class, new SvgDrawableTranscoder()) .append(InputStream.class, SVG.class, new SvgDecoder()); } }
3. 修改加载代码
移除多余的线程操作,指定Glide加载SVG为PictureDrawable类型:
import android.widget.ImageView; import com.bumptech.glide.load.DataSource; import com.bumptech.glide.load.engine.GlideException; import com.bumptech.glide.request.RequestListener; import com.bumptech.glide.request.target.Target; import androidx.annotation.Nullable; private void loadImage(String country, ImageView flag) { String pUrl = "https://hatscripts.github.io/circle-flags/flags/" + country.toLowerCase() + ".svg"; GlideApp.with(flag.getContext()) .as(PictureDrawable.class) .listener(new RequestListener<PictureDrawable>() { @Override public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<PictureDrawable> target, boolean isFirstResource) { // 可在此添加加载失败后的 fallback 逻辑 return false; } @Override public boolean onResourceReady(PictureDrawable resource, Object model, Target<PictureDrawable> target, DataSource dataSource, boolean isFirstResource) { flag.setScaleType(ImageView.ScaleType.CENTER_INSIDE); return false; } }) .load(pUrl) .override(120, 120) .into(flag); }
关键说明
- 必须通过
as(PictureDrawable.class)明确告诉Glide要加载的是SVG矢量图,否则Glide会默认按位图处理 - 移除多余的线程操作:Glide的
load()和into()方法已经内部处理了异步加载,无需手动创建线程 - 设置合适的
ScaleType:SVG是矢量图,使用CENTER_INSIDE或FIT_CENTER可以保证图片不失真
内容的提问来源于stack exchange,提问作者Christian Neri
相关产品推荐
相关产品推荐

