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

Glide 4.1.1: crash when attempting to preload images without a locked GlideRequest #2379

Closed
sheamartinson opened this issue Sep 12, 2017 · 7 comments
Milestone

Comments

@sheamartinson
Copy link

sheamartinson commented Sep 12, 2017

Glide Version: 4.1.1

Integration libraries:

    compile 'com.github.bumptech.glide:glide:4.1.1'
    compile 'com.github.bumptech.glide:okhttp3-integration:4.1.1'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.1.1'
    compile ('com.github.bumptech.glide:recyclerview-integration:4.1.1') {
        transitive = false
    }

Device/Android Version: Nexus 6P 7.1.1

Issue details / Repro steps / Use case background:
I am using the recyclerview integration library to preload images in a recyclerview that is displaying thousands of photos in a gridview.

The preloader is initialized like so:

    ViewPreloadSizeProvider<TimelineItem> sizeProvider = new ViewPreloadSizeProvider<>();
    RecyclerViewPreloader<TimelineItem> preloader =
            new RecyclerViewPreloader<>(GlideApp.with(context),
                    adapter,
                    sizeProvider,
                    IMAGE_PRELOAD_COUNT); // 10
    photosGrid.addOnScrollListener(preloader);

The crash happens when the recycler view is scrubbed. ie, when a scrubber is grabbed and rapidly moved around. I haven't been able to reproduce the error with regular scrolling. I have played around with the adapter that is implementing the PreloadModelProvider.

case 1: this request works and has not crashed

the locked requests:

protected final GlideRequest<Drawable> fullRequest;
protected final GlideRequest<Drawable> thumbRequest;

    fullRequest = glideManager
            .asDrawable()
            .centerCrop()
            .placeholder(R.drawable.media_placeholder);
    thumbRequest = glideManager
            .asDrawable()
            .centerCrop()
            .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
            .override(50)
            .transition(DrawableTransitionOptions.withCrossFade());

the request from getPreloadRequestBuilder:

fullRequest.load(o).thumbnail(thumbRequest.load(o));

The reason that I'm not satisfied using this request is that the items in the GridView are likely to be modified, so I need to use a signature to ensure that the cache is invalidated when this occurs.

case 2: cloning the request and adding a signature, crashes immediately when scrubbing

fullRequest.clone().load(o).signature(key).thumbnail(thumbRequest.clone().load(o).signature(key));

case 3: creating a new request using a GlideRequests object provided to the adapter, crashes immediately when scrubbing

glideManager.load(o)
                .signature(key)
                .centerCrop()
                .placeholder(R.drawable.media_placeholder)
                .thumbnail(glideManager.load(o)
                        .signature(key)
                        .centerCrop()
                        .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
                        .override(50)
                        .transition(DrawableTransitionOptions.withCrossFade()));

Stack trace / LogCat:

java.lang.IllegalArgumentException: You must call #load() before calling #into()
                                                                                          at com.bumptech.glide.RequestBuilder.into(RequestBuilder.java:355)
                                                                                          at com.bumptech.glide.ListPreloader.preloadItem(ListPreloader.java:183)
                                                                                          at com.bumptech.glide.ListPreloader.preloadAdapterPosition(ListPreloader.java:168)
                                                                                          at com.bumptech.glide.ListPreloader.preload(ListPreloader.java:151)
                                                                                          at com.bumptech.glide.ListPreloader.preload(ListPreloader.java:132)
                                                                                          at com.bumptech.glide.ListPreloader.onScroll(ListPreloader.java:120)
                                                                                          at com.bumptech.glide.integration.recyclerview.RecyclerToListViewScrollListener.onScrolled(RecyclerToListViewScrollListener.java:55)
                                                                                          at com.bumptech.glide.integration.recyclerview.RecyclerViewPreloader.onScrolled(RecyclerViewPreloader.java:88)
                                                                                          at android.support.v7.widget.RecyclerView.dispatchOnScrolled(RecyclerView.java:4626)
                                                                                          at android.support.v7.widget.RecyclerView.dispatchLayoutStep3(RecyclerView.java:3696)
                                                                                          at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3340)
                                                                                          at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3867)
                                                                                          at android.view.View.layout(View.java:17637)
                                                                                          at android.view.ViewGroup.layout(ViewGroup.java:5575)
                                                                                          at android.support.v4.widget.SwipeRefreshLayout.onLayout(SwipeRefreshLayout.java:636)
                                                                                          at android.view.View.layout(View.java:17637)
                                                                                          at android.view.ViewGroup.layout(ViewGroup.java:5575)
                                                                                          at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1079)
                                                                                          at android.view.View.layout(View.java:17637)
                                                                                          at android.view.ViewGroup.layout(ViewGroup.java:5575)
                                                                                          at android.support.v4.view.ViewPager.onLayout(ViewPager.java:1795)
                                                                                          at android.view.View.layout(View.java:17637)
                                                                                          at android.view.ViewGroup.layout(ViewGroup.java:5575)
                                                                                          at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
                                                                                          at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
                                                                                          at android.view.View.layout(View.java:17637)
                                                                                          at android.view.ViewGroup.layout(ViewGroup.java:5575)
                                                                                          at android.support.design.widget.CoordinatorLayout.layoutChild(CoordinatorLayout.java:1167)
                                                                                          at android.support.design.widget.CoordinatorLayout.onLayoutChild(CoordinatorLayout.java:852)
                                                                                          at android.support.design.widget.CoordinatorLayout.onLayout(CoordinatorLayout.java:871)
                                                                                          at android.view.View.layout(View.java:17637)
                                                                                          at android.view.ViewGroup.layout(ViewGroup.java:5575)
                                                                                          at android.support.v4.widget.DrawerLayout.onLayout(DrawerLayout.java:1193)
                                                                                          at android.view.View.layout(View.java:17637)
                                                                                          at android.view.ViewGroup.layout(ViewGroup.java:5575)
                                                                                          at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
                                                                                          at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
                                                                                          at android.view.View.layout(View.java:17637)
                                                                                          at android.view.ViewGroup.layout(ViewGroup.java:5575)
                                                                                          at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
                                                                                          at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
                                                                                          at android.view.View.layout(View.java:17637)
                                                                                          at android.view.ViewGroup.layout(ViewGroup.java:5575)
                                                                                          at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
                                                                                          at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
                                                                                          at android.view.View.layout(View.java:17637)
                                                                                          at android.view.ViewGroup.layout(ViewGroup.java:5575)
                                                                                          at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1741)
                                                                                          at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1585)
                                                                                          at android.widget.LinearLayout.onLayout(LinearLayout.java:1494)
                                                                                          at android.view.View.layout(View.java:17637)
                                                                                          at android.view.ViewGroup.layout(ViewGroup.java:5575)
                                                                                          at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
                                                                                          at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
                                                                                          at com.android.internal.policy.DecorView.onLayout(DecorView.java:727)
                                                                                          at android.view.View.layout(View.java:17637)
                                                                                          at android.view.ViewGroup.layout(ViewGroup.java:5575)
                                                                                          at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2346)   at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2068)
                                                                                          at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1254)
                                                                                          at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6338)
                                                                                          at android.view.Choreographer$CallbackRecord.run(Choreographer.java:874)
                                                                                          at android.view.Choreographer.doCallbacks(Choreographer.java:686)
                                                                                          at android.view.Choreographer.doFrame(Choreographer.java:621)
                                                                                          at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:860)
                                                                                          at android.os.Handler.handleCallback(Handler.java:751)
                                                                                          at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                          at android.os.Looper.loop(Looper.java:154)
                                                                                          at android.app.ActivityThread.main(ActivityThread.java:6121)
                                                                                          at java.lang.reflect.Method.invoke(Native Method)
                                                                                          at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
                                                                                          at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)
@sjudd sjudd added the bug label Sep 12, 2017
@sjudd sjudd added this to the 4.2 milestone Sep 12, 2017
@sjudd
Copy link
Collaborator

sjudd commented Sep 12, 2017

Can you show the full implementation of your ListPreloader.PreloadModelProvider, whatever version currently crashes?

@sheamartinson
Copy link
Author

public abstract class ItemAdapter implements ListPreloader.PreloadModelProvider<TimelineItem> {
    


    protected final GlideRequest<Drawable> fullRequest;
    protected final GlideRequest<Drawable> thumbRequest;
    private final ViewPreloadSizeProvider<TimelineItem> sizeProvider;
    private WeakReference<TimelineFragment> timelineFragment;


    public ItemAdapter(GlideRequests mngr, ViewPreloadSizeProvider<TimelineItem> sizeProvider, TimelineFragment timelineFragment) {

        this.sizeProvider = sizeProvider;
        this.timelineFragment = new WeakReference<>(timelineFragment);
        fullRequest = mngr
                .asDrawable()
                .centerCrop()
                .placeholder(R.drawable.media_placeholder);
        thumbRequest = mngr
                .asDrawable()
                .centerCrop()
                .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
                .override(50)
                .transition(DrawableTransitionOptions.withCrossFade());
    }

    protected boolean isItemHeader(int position) {
        return MemoryTimeline.getInstance().isHeader(position);
    }

    @Override
    public List<TimelineItem> getPreloadItems(int position) {
        if (timelineFragment == null || isItemHeader(position)) return new ArrayList<>();

        MetadataLoader loader = timelineFragment.get().getMetadataLoader();
        if (loader == null) return new ArrayList<>();

        List<TimelineItem> aList = new ArrayList<>(1);
        aList.add(loader.getItem(position));
        return aList;
    }
    
    @Override
    public RequestBuilder getPreloadRequestBuilder(TimelineItem item) {
        if (item == null) {
            return fullRequest;
        }
        Object o = item.isLocal() ? Uri.fromFile(item.getLocalFile()) :
                new GlideUrlCustom(item.getRemotePhoto().thumbnailUrl + ".s", item.getId() + ".s");

        ObjectKey key = new ObjectKey(item.getIdentifier());

        return fullRequest.clone()
                .signature(key)
                .load(o)
                .thumbnail(thumbRequest.clone()
                        .signature(key)
                        .load(o));
    }
}

@jackvt93
Copy link

jackvt93 commented Sep 13, 2017

I just have the same a few hour ago.
I guess that since we use "asDrawable" this problem occurs.

Please help me

@sjudd
Copy link
Collaborator

sjudd commented Sep 14, 2017

@sheamartinson if item == null, then you return the full request, which doesn't have a model set on it. If you filter out null items in your getPreloadItems() method above instead of adding them to the list, does it work?

@sjudd
Copy link
Collaborator

sjudd commented Sep 14, 2017

@jackvt93 Can you show your code just like @sheamartinson did above?

sjudd added a commit to sjudd/glide that referenced this issue Sep 14, 2017
@sjudd sjudd removed the bug label Sep 15, 2017
@sheamartinson
Copy link
Author

@sjudd it does work if I filter out null items! In my implementation it's a little unpredictable knowing what will be sent to the preloader because the RecyclerView is a mix of text-only headers and thumbnails. Calling .load(null) fixes the crash though.

@sjudd
Copy link
Collaborator

sjudd commented Sep 15, 2017

Great thanks. I've tried to make the code a little more lenient here as well, probably good enough to start with.

@sjudd sjudd closed this as completed Sep 15, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants