glide icon indicating copy to clipboard operation
glide copied to clipboard

Glide cannot load gif resources located in dynamic feature module.

Open JunyeongSeok opened this issue 3 years ago • 0 comments

Glide Version: 4.13.0

Integration libraries: None

Device/Android Version: Samsung Galaxy Note 20 / Android 10

Issue details / Repro steps / Use case background: Glide cannot load gif resources that located in the dynamic feature module. If I don't specify the TranscodeType type with asGif(), it works fine.

I debugged a bit of this issue and I found the ResourceLoader creates an URI of given resource, but it's invalid due to the nature of the dynamic feature module. (refer to Building a URI for a resource)

So, I made an extension function as a workaround.

fun <T> RequestBuilder<T>.loadLookup(context: Context, resId: Int): RequestBuilder<T> {
    val resources = context.resources
    val uri = Uri.Builder()
        .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
        .authority(context.packageName) // Look up the resources in the application with its splits loaded
        .appendPath(resources.getResourceTypeName(resId))
        .appendPath(
            String.format(
                "%s:%s",
                resources.getResourcePackageName(resId),
                resources.getResourceEntryName(resId)
            )
        ) // Look up the dynamic resource in the split namespace.
        .build()
    return load(uri)
}

// in Activity
Glide.with(this)
    .asGif()
    .loadLookup(this, R.drawable.sample)
    .into(image)

See the difference between URIs with load(R.drawable.sample):

android.resource://com.example.glidedfmproblem.dynamicfeature/drawable/sample

and loadLookup(this, R.drawable.sample):

android.resource://com.example.glidedfmproblem/drawable/com.example.glidedfmproblem.dynamicfeature%3Asample

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

// in Activity
val image = findViewById<ImageView>(R.id.my_image)
Glide.with(context)
    .asGif()
    .load(R.drawable.sample) // dynamicfeature/src/main/res/drawable/sample.gif
    .into(image)

Layout XML:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white">

    <ImageView
        android:id="@+id/my_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        tools:ignore="ContentDescription" />
</FrameLayout>

Stack trace / LogCat:

2022-03-29 19:16:30.788 6760-6760/com.example.glidedfmproblem W/Glide: Load failed for 2113994752 with size [2182x2182]
    class com.bumptech.glide.load.engine.GlideException: Failed to load resource
    There was 1 root cause:
    java.io.FileNotFoundException(No package found for authority: android.resource://com.example.glidedfmproblem.dynamicfeature/drawable/sample)
     call GlideException#logRootCauses(String) for more detail
      Cause (1 of 1): class com.bumptech.glide.load.engine.GlideException: Fetching data failed, class java.io.InputStream, LOCAL
    There was 1 root cause:
    java.io.FileNotFoundException(No package found for authority: android.resource://com.example.glidedfmproblem.dynamicfeature/drawable/sample)
     call GlideException#logRootCauses(String) for more detail
        Cause (1 of 1): class com.bumptech.glide.load.engine.GlideException: Fetch failed
    There was 1 root cause:
    java.io.FileNotFoundException(No package found for authority: android.resource://com.example.glidedfmproblem.dynamicfeature/drawable/sample)
     call GlideException#logRootCauses(String) for more detail
          Cause (1 of 1): class java.io.FileNotFoundException: No package found for authority: android.resource://com.example.glidedfmproblem.dynamicfeature/drawable/sample
2022-03-29 19:16:30.788 6760-6760/com.example.glidedfmproblem I/Glide: Root cause (1 of 1)
    java.io.FileNotFoundException: No package found for authority: android.resource://com.example.glidedfmproblem.dynamicfeature/drawable/sample
        at android.content.ContentResolver.getResourceId(ContentResolver.java:1778)
        at android.content.ContentResolver.openInputStream(ContentResolver.java:1182)
        at com.bumptech.glide.load.data.StreamLocalUriFetcher.loadResourceFromUri(StreamLocalUriFetcher.java:74)
        at com.bumptech.glide.load.data.StreamLocalUriFetcher.loadResource(StreamLocalUriFetcher.java:50)
        at com.bumptech.glide.load.data.StreamLocalUriFetcher.loadResource(StreamLocalUriFetcher.java:13)
        at com.bumptech.glide.load.data.LocalUriFetcher.loadData(LocalUriFetcher.java:44)
        at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.loadData(MultiModelLoader.java:100)
        at com.bumptech.glide.load.engine.SourceGenerator.startNextLoad(SourceGenerator.java:95)
        at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:88)
        at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:311)
        at com.bumptech.glide.load.engine.DecodeJob.runWrapped(DecodeJob.java:280)
        at com.bumptech.glide.load.engine.DecodeJob.run(DecodeJob.java:235)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultThreadFactory$1.run(GlideExecutor.java:413)
        at java.lang.Thread.run(Thread.java:919)
        at com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultPriorityThreadFactory$1.run(GlideExecutor.java:372)

Demo project: https://github.com/JunyeongSeok/GlideDfmProblem

JunyeongSeok avatar Mar 29 '22 09:03 JunyeongSeok