当前位置: 首页> 健康> 美食 > 前端项目_电子商务seo是什么_石家庄全网seo_运营商推广5g技术

前端项目_电子商务seo是什么_石家庄全网seo_运营商推广5g技术

时间:2025/7/13 4:21:20来源:https://blog.csdn.net/u013762572/article/details/147614943 浏览次数:0次
前端项目_电子商务seo是什么_石家庄全网seo_运营商推广5g技术

最近有个需求,后端给出的图片地址并不是正常的 URL,而且需要一个接口去请求,但是返回的是 base64 数据流。这里不关心为啥要这么多,原因有很多,可能是系统的问题,也可能是能力问题。当然作为我们 Android 程序员,要紧的是如何解决这个问题。

首先我们拿到接口链接,我这次拿到的是这样的:

https://www.example.com/cdn/attach/{fileId}/base64

这里的{fileId} 是指图片的 id,那么正常的图片地址可以理解为:

https://www.example.com/cdn/attach/1000/base64
https://www.example.com/cdn/attach/1002/base64

熟悉 Glide 加载逻辑的人,应该很熟悉,这种方式可能需要我们自定义ModelLoader 来解决问题,们可以让 Glide 将 API 接口当作一种图片源来处理,就像处理普通的图片 URL 一样。

实现方案

我们可以自定义 Base64ApiModelLoader 来处理 base64 的请求数据:

public class Base64ApiModelLoader implements ModelLoader<String, InputStream> {private static final String BASE_URL = "https://your-api-base-url/";private static final String API_PATH = "cdn/attach/";private final OkHttpClient okHttpClient;public Base64ApiModelLoader() {this.okHttpClient = new OkHttpClient.Builder().connectTimeout(15, TimeUnit.SECONDS).readTimeout(15, TimeUnit.SECONDS).build();}@Nullable@Overridepublic LoadData<InputStream> buildLoadData(@NonNull String fileId, int width, int height, @NonNull Options options) {// 创建缓存键,使用文件ID作为唯一标识Key key = new ObjectKey(API_PATH + fileId);// 返回加载数据,包含缓存键和数据获取器return new LoadData<>(key, new Base64ApiFetcher(fileId, okHttpClient));}@Overridepublic boolean handles(@NonNull String model) {// 判断是否是文件ID格式,这里简单判断不是URLreturn !model.startsWith("http") && !model.startsWith("data:");}// 工厂类,用于创建ModelLoaderpublic static class Factory implements ModelLoaderFactory<String, InputStream> {@NonNull@Overridepublic ModelLoader<String, InputStream> build(@NonNull MultiModelLoaderFactory multiFactory) {return new Base64ApiModelLoader();}@Overridepublic void teardown() {// 清理资源}}// 数据获取器,负责从API获取Base64数据并转换为InputStreamprivate static class Base64ApiFetcher implements DataFetcher<InputStream> {private final String fileId;private final OkHttpClient okHttpClient;private InputStream inputStream;private volatile boolean isCancelled;Base64ApiFetcher(String fileId, OkHttpClient okHttpClient) {this.fileId = fileId;this.okHttpClient = okHttpClient;}@Overridepublic void loadData(@NonNull Priority priority, @NonNull DataCallback<? super InputStream> callback) {if (isCancelled) {callback.onLoadFailed(new IOException("Cancelled"));return;}// 构建API请求URLString apiUrl = BASE_URL + API_PATH + fileId + "/base64";Request request = new Request.Builder().url(apiUrl).build();try {// 执行请求Response response = okHttpClient.newCall(request).execute();if (!response.isSuccessful()) {callback.onLoadFailed(new IOException("Failed to load Base64 data: " + response.code()));return;}// 解析响应体ResponseBody responseBody = response.body();if (responseBody == null) {callback.onLoadFailed(new IOException("Empty response"));return;}// 解析JSON响应String jsonString = responseBody.string();JSONObject jsonObject = new JSONObject(jsonString);// 检查响应码int code = jsonObject.optInt("code", -1);if (code != 200) {callback.onLoadFailed(new IOException("API error: " + jsonObject.optString("message", "Unknown error")));return;}// 获取Base64数据String base64Data = jsonObject.optString("data", "");if (base64Data.isEmpty()) {callback.onLoadFailed(new IOException("Empty Base64 data"));return;}// 处理可能存在的Data URI前缀if (base64Data.contains(",")) {base64Data = base64Data.split(",")[1];}// 解码Base64数据byte[] imageBytes = Base64.decode(base64Data, Base64.DEFAULT);// 创建输入流inputStream = new ByteArrayInputStream(imageBytes);// 回调成功callback.onDataReady(inputStream);} catch (IOException | JSONException | IllegalArgumentException e) {if (!isCancelled) {callback.onLoadFailed(e);}}}@Overridepublic void cleanup() {if (inputStream != null) {try {inputStream.close();} catch (IOException ignored) {// 忽略关闭错误}}}@Overridepublic void cancel() {isCancelled = true;}@NonNull@Overridepublic Class<InputStream> getDataClass() {return InputStream.class;}@NonNull@Overridepublic DataSource getDataSource() {return DataSource.REMOTE;}}
}

定义完成ModelLoader之后,我们可能就要注册ModelLoader了。


@GlideModule
public class MyAppGlideModule extends AppGlideModule {@Overridepublic void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {super.registerComponents(context, glide, registry);// 注册我们的自定义ModelLoader,用于处理Base64 API请求registry.append(String.class, InputStream.class, new Base64ApiModelLoader.Factory());}@Overridepublic boolean isManifestParsingEnabled() {return false;}
}

当然不能忘记需要有注解处理器

annotationProcessor 'com.github.bumptech.glide:compiler:4.15.1'

处理完之后,我们就可以这么调用了:

		Glide.with(imageView.getContext()).load(fileId)  // +.placeholder(R.mipmap.default_image).error(R.mipmap.default_image).into(imageView);

我们之前 load 方法中一直调用的是 url, 这里就直接调用 fileId 即可。因为我们已经定义了

registry.append(String.class, InputStream.class, new Base64ApiModelLoader.Factory());

其他地方都不变,即可正常进行请求了。

关键字:前端项目_电子商务seo是什么_石家庄全网seo_运营商推广5g技术

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: