I am trying to load a custom model in Glide, but I get this error:
GlideExecutor: request was thrown by the immovable com.bumptech.glide.Registry $ NoModelLoaderAvailableException: could not find ModelLoaders models for model: com.company.project.glide.Movie@aac331a
Glide Version : 4.0.0
My codes are:
Model
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; } }
Module
@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()); } }
ModelLoader
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");
Then I load it like this:
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);
Please, where am I mistaken?
EDIT
I applied the answer below, but I started getting NPE. This is stacktrace:
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$1.run(GlideExecutor.java:347)