解决com.bumptech.glide.Registry$NoModelLoaderAvailableException(Failed to find any ModelLoaders for...

解决Android中出现GlideExecutor: Request threw uncaught throwable com.bumptech.glide.Registry$NoModelLoaderAvailableException: Failed to find any ModelLoaders registered for model class

报错信息如下:

GlideExecutor: Request threw uncaught throwable
    com.bumptech.glide.Registry$NoModelLoaderAvailableException: Failed to find any ModelLoaders registered for model class: class com.example.zzz.CloudImageModel
        at com.bumptech.glide.load.model.ModelLoaderRegistry.getModelLoaders(ModelLoaderRegistry.java:77)
        at com.bumptech.glide.Registry.getModelLoaders(Registry.java:588)
        at com.bumptech.glide.load.engine.DecodeHelper.getLoadData(DecodeHelper.java:207)
        at com.bumptech.glide.load.engine.DecodeHelper.getCacheKeys(DecodeHelper.java:224)
        at com.bumptech.glide.load.engine.ResourceCacheGenerator.startNext(ResourceCacheGenerator.java:44)
        at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:311)
        at com.bumptech.glide.load.engine.DecodeJob.runWrapped(DecodeJob.java:277)
        at com.bumptech.glide.load.engine.DecodeJob.run(DecodeJob.java:235)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:919)
        at com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultThreadFactory$1.run(GlideExecutor.java:393)

这是Glide加载图片时出现的异常。异常信息显示没有类型为CloudImageModel的模型类注册任何ModelLoader。这可能是因为在Glide初始化时,没有为该类型的模型注册ModelLoader。你可以检查一下相关的代码,看是否有为该模型注册ModelLoader的代码。需要注意的是,Glide中不支持所有类型的数据源,因此需要为自定义的数据源注册相应的ModelLoader。

在加载图片时,Glide 找不到任何已注册的模型加载器来处理 CloudImageModel 类型的数据。这可能由于以下几个问题导致:

  1. 对应的模型加载器没有被正确地注册到 Glide 中。
  2. 模型加载器注册成功,但有可能存在缺陷或者功能不完备(图片地址错误等)造成无法加载数据。

解决此问题的方法包括:

  1. 确认 CloudImageModel 类型的数据已经正确地在应用代码中生成或处理。
  2. 检查是否已经将对应的模型加载器正确地注册到了 Glide 中。
  3. 确认模型加载器是否实现正确且没有其他异常问题。
  4. 确认网络请求是否正常,URL 是否可用,并检查与此有关的所有权限和配置是否正常。

通过上述方法可以尝试解决该异常问题。

怎么确认 CloudImageModel 类型的数据已经正确地在应用代码中生成或处理并检查是否已经将对应的模型加载器正确地注册到了 Glide 中呢?

  1. 首先确认 CloudImageModel 类型的数据是否已经正确生成或处理。可以检查使用该数据的代码,确保它们正确遵循了该类的定义。确保传递给 Glide 加载图片的参数类型是正确的。
  2. 确认是否已经将对应的模型加载器正确地注册到了 Glide 中。可以检查应用的代码,并按照以下步骤查看是否已经注册成功:
  3. 确认在应用的 build.gradle 文件中添加了相应的 Glide 依赖。
    创建一个自定义的 GlideModule 实现类,继承 LibraryGlideModule 或 AppGlideModule,根据具体需要重写相应方法。确保重写了 registerComponents() 方法并注册了 CloudImageModel 对应的模型加载器。
  4. 在 AndroidManifest.xml 中加入 CustomAppGlideModule 的声明。
    如果发现没有注册成功,可以参考 Glide 官方文档,检查是否完成了 GlideModule 的正确配置和注册。

需要注意的是如果你使用的是新版的 Glide 4.x,它的注册方式已经有所变化,请仔细阅读 Glide 官方文档。
下面是一个简单的示例,展示如何在 registerComponents() 方法中注册 CloudImageModel 对应的模型加载器:

@GlideModule
public class CustomGlideModule extends AppGlideModule {
    @Override
    public void registerComponents(Context context, Glide glide, Registry registry) {
        // 注册自定义模型加载器 CloudImageModelLoader
        registry.append(CloudImageModel.class, InputStream.class, new CloudImageModelLoader.Factory());
    }
}

在上述代码中,我们创建了一个名为 CustomGlideModule 的 AppGlideModule 子类,并重写了 registerComponents() 方法。该方法使用 Registry.append() 方法,将 CloudImageModel 类型和 InputStream 类型相关联,并注册 CloudImageModelLoader。

public class CloudImageModel {
    private final String url;

    public CloudImageModel(String url) {
        this.url = url;
    }

    public String getUrl() {
        return url;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null || getClass() != obj.getClass()) {
            return false;
        }
        CloudImageModel other = (CloudImageModel) obj;
        return url.equals(other.url);
    }

    @Override
    public int hashCode() {
        return url.hashCode();
    }
}

上述代码表示了一个简单的 CloudImageModel 类,包含一个从字符串中构造的 URL 地址,并实现了 hashCode() 和 equals() 方法。
接下来是自定义模型加载器 CloudImageModelLoader 的实现,它将 CloudImageModel 对象转换为 InputStream。
需要注意的是,CloudImageModelLoader 需要实现 ModelLoader.Factory 接口的 build() 和 teardown() 方法。

public class CloudImageModelLoader implements ModelLoader<CloudImageModel, InputStream> {

    public static class Factory implements ModelLoaderFactory<CloudImageModel, InputStream> {

        @NonNull
        @Override
        public ModelLoader<CloudImageModel, InputStream> build(@NonNull MultiModelLoaderFactory multiFactory) {
            return new CloudImageModelLoader();
        }

        @Override
        public void teardown() {
        }
    }

    @Nullable
    @Override
    public LoadData<InputStream> buildLoadData(@NonNull CloudImageModel model, int width, int height, @NonNull Options options) {
        return new LoadData<>(new ObjectKey(model), new CloudImageFetcher(model));
    }

    @Override
    public boolean handles(@NonNull CloudImageModel model) {
        return true;
    }
}

public class CloudImageFetcher implements DataFetcher<InputStream> {
    private final CloudImageModel model;

    public CloudImageFetcher(CloudImageModel model) {
        this.model = model;
    }

    @Override
    public void loadData(@NonNull Priority priority, @NonNull DataCallback<? super InputStream> callback) {
       // 这里实现具体的数据加载逻辑,返回 InputStream 对象
        // 注意:这里需要考虑缓存、重试等机制。
        // 这个实现可能需要和你的后端 API 接口对接。这里简单实现只是作为示例。
        String imageUrl = "http://myserver.com/image/deviceId=" + model.getDeviceId() + "&imageName=" + model.getImageName() + "&imageTime=" + model.getImageTime();
        try {
            URL url = new URL(imageUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.connect();
            if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                InputStream inputStream = connection.getInputStream();
                callback.onDataReady(inputStream);
                return;
            }
        } catch (Exception e) {
            Log.e(TAG, "loadData: ", e);
        }
        callback.onLoadFailed(new Exception("Failed to load image"));
    }

    @Override
    public void cleanup() {
    }

    @Override
    public void cancel() {
    }

    @NonNull
    @Override
    public Class<InputStream> getDataClass() {
        return InputStream.class;
    }

    @NonNull
    @Override
    public DataSource getDataSource() {
        return DataSource.REMOTE;
    }
}

CloudImage 实现了 Glide 中的 Model 接口,并包装了 CloudImageModel 对象;CloudImageModelLoader 实现了 ModelLoader 接口,用于将 CloudImageModel 转换为输入流,并加载到 Glide 中;CloudImageFetcher 实现了 DataFetcher 接口,负责实现真正的数据加载逻辑。

需要注意的是,以上实现只是一个示例。如果你的具体业务场景和后端 API 不同,你可能需要对 CloudImageFetcher 进行更复杂的实现。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值