com.bumptech.glide.Registry$NoModelLoaderAvailableException:找不到任何模型加载器
com.bumptech.glide.Registry$NoModelLoaderAvailableException: Failed to find any ModelLoaders
我正在尝试将自定义模型加载到 Glide 中,但出现此错误:
GlideExecutor: Request threw uncaught throwable
com.bumptech.glide.Registry$NoModelLoaderAvailableException: Failed to
find any ModelLoaders for model:
com.company.project.glide.Movie@aac331a
Glide 版本: 4.0.0
我的代码:
型号
public class Movie {
private String name;
private String artist;
public Movie(String name, String artist) {
this.name = name;
this.artist = artist;
}
public String getName() {
return name;
}
public String getArtist() {
return artist;
}
}
模块
@com.bumptech.glide.annotation.GlideModule
public class GlideModule extends AppGlideModule {
@Override
public boolean isManifestParsingEnabled() {
return false;
}
@Override
public void applyOptions(Context context, GlideBuilder builder) {
super.applyOptions(context, builder);
}
@Override
public void registerComponents(Context context, Registry registry) {
registry.append(Movie.class, InputStream.class, new MovieArtModel.Factory());
}
}
模型加载器
public class MovieArtModel implements ModelLoader<Movie, InputStream> {
@Nullable
@Override
public LoadData<InputStream> buildLoadData(Movie movie, int width, int height, Options options) {
Timber.d("buildLoadData: ");
return new LoadData<>(new ObjectKey(movie), new MovieArtLoader(movie, width, height));
}
@Override
public boolean handles(Movie movie) {
return false;
}
public static class Factory implements ModelLoaderFactory<Movie, InputStream> {
@Override
public ModelLoader<Movie, InputStream> build(MultiModelLoaderFactory multiFactory) {
return new MovieArtModel();
}
@Override
public void teardown() {
}
}
static class MovieArtLoader implements DataFetcher<InputStream> {
private Movie movie;
private boolean isCancelled = false;
private int widthSize;
private int heightSize;
MovieArtLoader(Movie movie, int widthSize, int heightSize) {
Timber.d("MovieArtLoader: Initializing...width size = " + widthSize + " :: heightSize = " + heightSize);
this.movie = movie;
this.widthSize = widthSize;
this.heightSize = heightSize;
}
@Override
public void loadData(Priority priority, DataCallback<? super InputStream> callback) {
Timber.d("loadData");
//First check if request is not cancelled before starting request
if(!isCancelled()) {
InputStream inputStream = getMovieArtInputStream(movie);
if (inputStream != null) {
callback.onDataReady(inputStream);
} else {
callback.onLoadFailed(new IOException("Forced Glide network failure. Can't load Movie image"));
}
}
}
return null;
}
@Override public void cleanup() {
Timber.d("cleanup: ");
}
@Override public void cancel() {
Timber.d("cancel: ");
isCancelled = true;
}
@Override
public Class<InputStream> getDataClass() {
return null;
}
@Override
public DataSource getDataSource() {
return null;
}
private boolean isCancelled() {
return isCancelled;
}
}
那我是这样加载的:
GlideApp.with(itemView.getContext())
.asBitmap()
.load(new Movie(book.getMovieName(), book.getArtist()))
.placeholder(R.drawable.movie_default_small)
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
.listener(this)
.into(imageView);
请问我哪里弄错了?
编辑
我应用了下面的答案,但我开始出现 NPE。这是堆栈跟踪:
E/GlideExecutor: Request threw uncaught throwable
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Object.hashCode()' on a null object reference
at com.bumptech.glide.util.MultiClassKey.hashCode(MultiClassKey.java:66)
at android.support.v4.util.SimpleArrayMap.indexOfKey(SimpleArrayMap.java:320)
at android.support.v4.util.SimpleArrayMap.get(SimpleArrayMap.java:360)
at com.bumptech.glide.provider.LoadPathCache.get(LoadPathCache.java:34)
at com.bumptech.glide.Registry.getLoadPath(Registry.java:132)
at com.bumptech.glide.load.engine.DecodeHelper.getLoadPath(DecodeHelper.java:132)
at com.bumptech.glide.load.engine.DecodeHelper.hasLoadPath(DecodeHelper.java:128)
at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:59)
at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:282)
at com.bumptech.glide.load.engine.DecodeJob.runWrapped(DecodeJob.java:252)
at com.bumptech.glide.load.engine.DecodeJob.run(DecodeJob.java:222)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
at com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultThreadFactory.run(GlideExecutor.java:347)
@Override
public boolean handles(Movie movie) {
return true;
}
你需要这样做,否则 Glide 会忽略你的 ModelLoader,认为它不处理提供的 Movie
模型。
NoModelLoaderAvailableException 发生在没有
{@linkcom.bumptech.glide.load.model.ModelLoader} 已注册给定
模型 class,并用 @talkLittle 回答修复,加上那部电影应该实现 equals()
和 hashCode()
以使缓存正常工作。
新的 NPE 发生是因为您接受 @Nullable
会尝试 @NonNull
注释。
检查 .load
和 .into
:
Glide.with(this)
.load(check_here)
.apply(new RequestOptions().diskCacheStrategy(DiskCacheStrategy.NONE))
.into(new DrawableImageViewTarget(check_here));
我正在尝试将自定义模型加载到 Glide 中,但出现此错误:
GlideExecutor: Request threw uncaught throwable com.bumptech.glide.Registry$NoModelLoaderAvailableException: Failed to find any ModelLoaders for model: com.company.project.glide.Movie@aac331a
Glide 版本: 4.0.0
我的代码:
型号
public class Movie {
private String name;
private String artist;
public Movie(String name, String artist) {
this.name = name;
this.artist = artist;
}
public String getName() {
return name;
}
public String getArtist() {
return artist;
}
}
模块
@com.bumptech.glide.annotation.GlideModule
public class GlideModule extends AppGlideModule {
@Override
public boolean isManifestParsingEnabled() {
return false;
}
@Override
public void applyOptions(Context context, GlideBuilder builder) {
super.applyOptions(context, builder);
}
@Override
public void registerComponents(Context context, Registry registry) {
registry.append(Movie.class, InputStream.class, new MovieArtModel.Factory());
}
}
模型加载器
public class MovieArtModel implements ModelLoader<Movie, InputStream> {
@Nullable
@Override
public LoadData<InputStream> buildLoadData(Movie movie, int width, int height, Options options) {
Timber.d("buildLoadData: ");
return new LoadData<>(new ObjectKey(movie), new MovieArtLoader(movie, width, height));
}
@Override
public boolean handles(Movie movie) {
return false;
}
public static class Factory implements ModelLoaderFactory<Movie, InputStream> {
@Override
public ModelLoader<Movie, InputStream> build(MultiModelLoaderFactory multiFactory) {
return new MovieArtModel();
}
@Override
public void teardown() {
}
}
static class MovieArtLoader implements DataFetcher<InputStream> {
private Movie movie;
private boolean isCancelled = false;
private int widthSize;
private int heightSize;
MovieArtLoader(Movie movie, int widthSize, int heightSize) {
Timber.d("MovieArtLoader: Initializing...width size = " + widthSize + " :: heightSize = " + heightSize);
this.movie = movie;
this.widthSize = widthSize;
this.heightSize = heightSize;
}
@Override
public void loadData(Priority priority, DataCallback<? super InputStream> callback) {
Timber.d("loadData");
//First check if request is not cancelled before starting request
if(!isCancelled()) {
InputStream inputStream = getMovieArtInputStream(movie);
if (inputStream != null) {
callback.onDataReady(inputStream);
} else {
callback.onLoadFailed(new IOException("Forced Glide network failure. Can't load Movie image"));
}
}
}
return null;
}
@Override public void cleanup() {
Timber.d("cleanup: ");
}
@Override public void cancel() {
Timber.d("cancel: ");
isCancelled = true;
}
@Override
public Class<InputStream> getDataClass() {
return null;
}
@Override
public DataSource getDataSource() {
return null;
}
private boolean isCancelled() {
return isCancelled;
}
}
那我是这样加载的:
GlideApp.with(itemView.getContext())
.asBitmap()
.load(new Movie(book.getMovieName(), book.getArtist()))
.placeholder(R.drawable.movie_default_small)
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
.listener(this)
.into(imageView);
请问我哪里弄错了?
编辑
我应用了下面的答案,但我开始出现 NPE。这是堆栈跟踪:
E/GlideExecutor: Request threw uncaught throwable
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Object.hashCode()' on a null object reference
at com.bumptech.glide.util.MultiClassKey.hashCode(MultiClassKey.java:66)
at android.support.v4.util.SimpleArrayMap.indexOfKey(SimpleArrayMap.java:320)
at android.support.v4.util.SimpleArrayMap.get(SimpleArrayMap.java:360)
at com.bumptech.glide.provider.LoadPathCache.get(LoadPathCache.java:34)
at com.bumptech.glide.Registry.getLoadPath(Registry.java:132)
at com.bumptech.glide.load.engine.DecodeHelper.getLoadPath(DecodeHelper.java:132)
at com.bumptech.glide.load.engine.DecodeHelper.hasLoadPath(DecodeHelper.java:128)
at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:59)
at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:282)
at com.bumptech.glide.load.engine.DecodeJob.runWrapped(DecodeJob.java:252)
at com.bumptech.glide.load.engine.DecodeJob.run(DecodeJob.java:222)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
at com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultThreadFactory.run(GlideExecutor.java:347)
@Override
public boolean handles(Movie movie) {
return true;
}
你需要这样做,否则 Glide 会忽略你的 ModelLoader,认为它不处理提供的 Movie
模型。
NoModelLoaderAvailableException 发生在没有
{@linkcom.bumptech.glide.load.model.ModelLoader} 已注册给定
模型 class,并用 @talkLittle 回答修复,加上那部电影应该实现 equals()
和 hashCode()
以使缓存正常工作。
新的 NPE 发生是因为您接受 @Nullable
会尝试 @NonNull
注释。
检查 .load
和 .into
:
Glide.with(this)
.load(check_here)
.apply(new RequestOptions().diskCacheStrategy(DiskCacheStrategy.NONE))
.into(new DrawableImageViewTarget(check_here));