bumptech / glide

An image loading and caching library for Android focused on smooth scrolling
https://bumptech.github.io/glide/
Other
34.59k stars 6.12k forks source link

NoClassDefFoundError: com.bumptech.glide.load.resource.gif.GifBitmapProvider #2785

Closed nielsdelporte closed 6 years ago

nielsdelporte commented 6 years ago

Glide Version: 4.4.0

Integration libraries: OkHttp3-3.4.2

Device/Android Version: Fails on Samsung Galaxy Tab S 10.5/Samsung SM-T800 Android 6.0.1 and Google Pixel C Android 8.0

Issue details / Repro steps / Use case background: We were experiencing transformation issues with Glide 3.7.0 in our app, and only recently noticed that there were several updates available to the Glide library. Some of those updates contained fixes that might resolve our problems. We updated Glide to 4.4.0 and resolved all the build issues. We ran into issues when we tried to create a RequestManager with Glide.with(an instance of a Fragment).

Glide load line / GlideModule (if any) / list Adapter code (if any):

// Field definition
private RequestManager requestManager;
// Field initialisation in onAttach
// 'this' is a Fragment
this.requestManager = Glide.with(this);

This Fragment is used in a carousel of other fragments, each containing an image for showing a big thumbnail and a videoplayer for streaming video content. The app crashes because it can't find GifBitmapProvider when the LiveChannelFragment (the name of the class in question), and also the first Fragment the user encounters when opening our app. Layout XML of one item/fragment in the carousel:

<?xml version="1.0" encoding="utf-8"?>
<domain.myapp.views.live.CarouselItemViewGroup
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:id="@+id/container_fragment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/livetileview"
        android:layout_alignLeft="@+id/livetileview"
        android:layout_alignRight="@+id/livetileview"
        android:layout_alignTop="@+id/livetileview"
        android:layout_marginBottom="@dimen/main_tile_shadow_margin"
        android:layout_marginLeft="@dimen/main_tile_shadow_margin"
        android:layout_marginRight="@dimen/main_tile_shadow_margin"
        android:layout_marginTop="@dimen/main_tile_shadow_margin"
        android:background="@drawable/carousel_item_shadow"
        android:padding="@dimen/main_tile_shadow_padding"/>

    <domain.myapp.views.live.LiveTileView
        android:id="@+id/livetileview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        app:layout_widthPercent="@fraction/percent_main_tile"
        app:ratio="@dimen/image_ratio_main"/>

    <domain.myapp.views.TextView
        android:id="@+id/textview_live"
        style="@style/MyAppTheme.Live.TextView.LiveNow"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/livetileview"
        android:layout_alignLeft="@+id/livetileview"
        android:layout_marginBottom="@dimen/padding_medium"
        android:text="@string/live_now"/>

    <ImageButton
        android:id="@+id/button_close"
        android:layout_width="@dimen/detail_favorite_icon_size"
        android:layout_height="@dimen/detail_favorite_icon_size"
        android:layout_alignLeft="@+id/livetileview"
        android:layout_alignTop="@+id/livetileview"
        android:layout_marginLeft="@dimen/padding_large"
        android:layout_marginTop="@dimen/padding_large"
        android:background="?attr/selectableItemBackgroundBorderless"
        android:src="@drawable/ic_close"
        android:visibility="gone"
        tools:visibility="visible"/>

    <domain.myapp.views.Spinner
        android:id="@+id/spinner"
        android:layout_width="@dimen/main_tile_progress_image_width"
        android:layout_height="@dimen/main_tile_progress_image_height"
        android:layout_alignBottom="@id/livetileview"
        android:layout_alignRight="@id/livetileview"
        android:layout_marginBottom="@dimen/main_tile_progress_image_margin_bottom"
        android:layout_marginRight="@dimen/padding_large"
        android:visibility="gone"
        tools:visibility="visible"/>

    <FrameLayout
        android:id="@+id/button_carousel_cast_play"
        android:layout_centerInParent="true"
        android:visibility="gone"
        android:layout_width="@dimen/cast_carousel_play_background"
        android:layout_height="@dimen/cast_carousel_play_background"
        android:background="@drawable/bg_carousel_cast_play">

        <ImageView
            android:layout_gravity="center"
            android:layout_width="@dimen/cast_carousel_play_icon"
            android:layout_height="@dimen/cast_carousel_play_icon"
            android:src="@drawable/ic_ico_play"/>

    </FrameLayout>

</domain.myapp.views.live.CarouselItemViewGroup>

Stack trace / LogCat:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: myapp.debug, PID: 19948
    java.lang.NoClassDefFoundError: com.bumptech.glide.load.resource.gif.GifBitmapProvider
    at com.bumptech.glide.load.resource.gif.ByteBufferGifDecoder.<init>(ByteBufferGifDecoder.java:68)
    at com.bumptech.glide.load.resource.gif.ByteBufferGifDecoder.<init>(ByteBufferGifDecoder.java:54)
    at com.bumptech.glide.Glide.<init>(Glide.java:327)
    at com.bumptech.glide.GlideBuilder.build(GlideBuilder.java:445)
    at com.bumptech.glide.Glide.initializeGlide(Glide.java:257)
    at com.bumptech.glide.Glide.initializeGlide(Glide.java:212)
    at com.bumptech.glide.Glide.checkAndInitializeGlide(Glide.java:176)
    at com.bumptech.glide.Glide.get(Glide.java:160)
    at com.bumptech.glide.Glide.getRetriever(Glide.java:612)
    at com.bumptech.glide.Glide.with(Glide.java:684)
    at domain.myapp.fragments.live.LiveChannelFragment.onAttach(LiveChannelFragment.java:187)
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1363)
    at android.support.v4.app.FragmentTransition.addToFirstInLastOut(FragmentTransition.java:1109)
    at android.support.v4.app.FragmentTransition.calculateFragments(FragmentTransition.java:996)
    at android.support.v4.app.FragmentTransition.startTransitions(FragmentTransition.java:99)
    at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2364)
    at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2322)
    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2229)
    at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:781)
    at domain.myapp.adapters.fragment.FragmentRecyclerViewAdapter.onCreateViewHolder(FragmentRecyclerViewAdapter.java:127)
    at domain.myapp.adapters.fragment.FragmentRecyclerViewAdapter.onCreateViewHolder(FragmentRecyclerViewAdapter.java:37)
    at domain.myapp.views.recyclerview.RecyclerView$Adapter.createViewHolder(RecyclerView.java:6084)
    at domain.myapp.views.recyclerview.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5254)
    at domain.myapp.views.recyclerview.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5164)
    at domain.myapp.views.carousel.CarouselLayoutManager$LayoutState.next(CarouselLayoutManager.java:2080)
    at domain.myapp.views.carousel.CarouselLayoutManager.layoutChunk(CarouselLayoutManager.java:1424)
    at domain.myapp.views.carousel.CarouselLayoutManager.fill(CarouselLayoutManager.java:1387)
    at domain.myapp.views.carousel.CarouselLayoutManager.onLayoutChildren(CarouselLayoutManager.java:586)
    at domain.myapp.views.recyclerview.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3385)
    at domain.myapp.views.recyclerview.RecyclerView.dispatchLayout(RecyclerView.java:3194)
    at domain.myapp.views.recyclerview.RecyclerView.consumePendingUpdateOperations(RecyclerView.java:1599)
    at domain.myapp.views.recyclerview.RecyclerView$1.run(RecyclerView.java:325)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
    at android.view.Choreographer.doCallbacks(Choreographer.java:686)
    at android.view.Choreographer.doFrame(Choreographer.java:619)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:148)
    at android.app.ActivityThread.main(ActivityThread.java:7331)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
    at com.android.internal.os.Zygo
sjudd commented 6 years ago

This is some kind of build issue in your application. Maybe you're still including Glide v3, either directly or via some transitive dependency?

nielsdelporte commented 6 years ago

I've gone through all dependencies, either direct or transitive, but all glide dependencies were targeting version 4.4.0. I've listed these using the following command: ./gradlew app:dependencies

nielsdelporte commented 6 years ago

Resolved by including the complete library, as described in #2787 .

sjudd commented 6 years ago

Were you depending on com.bumptech.glide:glide:4.4.0@aar? Specifically the @aar part? if so the better answer is to add transitive = true to any dependencies where you use @aar. Gradle apparently interprets @anything as meaning you only want that specific archive.