Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NullPointerException: Attempt to invoke virtual method 'int java.lang.Object.hashCode()' #2272

Closed
wilburx9 opened this issue Aug 20, 2017 · 3 comments
Labels

Comments

@wilburx9
Copy link

Glide Version: 4.0.0

Integration libraries: None

Device/Android Version: Samsung Galaxy Core Prime

I am getting NPE while loading a custom model into Glide:

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)

My codes:

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");

            //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;
        }
    }

Then I am loading it thus:

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 getting it wrong?

@Tolriq
Copy link
Contributor

Tolriq commented Aug 21, 2017

 @Override
        public Class<InputStream> getDataClass() {
            return null;
        }

        @Override
        public DataSource getDataSource() {
            return null;
        }

Those can't return null.

Should be

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

        @Override
        public DataSource getDataSource() {
            return DataSource.REMOTE; // Or another value depending on where 
        }

See #2203

Edit and your custom model should correctly implements hashCode / equals.

@sjudd sjudd added the bug label Aug 21, 2017
@sjudd sjudd added this to the 4.1 milestone Aug 21, 2017
@sjudd sjudd removed the bug label Aug 21, 2017
@sjudd sjudd removed this from the 4.1 milestone Aug 21, 2017
@sjudd
Copy link
Collaborator

sjudd commented Aug 21, 2017

It turns out it's a pain to add a precondition for this everywhere, but the method is at least annotated @NonNull already.

@sjudd sjudd added the question label Aug 21, 2017
@wilburx9
Copy link
Author

Thanks, it's been fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants