bumptech / glide

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

LibraryGlideModule does not work after migrate to ksp. #5298

Open opLW opened 1 year ago

opLW commented 1 year ago

Glide: 4.16.0

1. Background introduction. I have a custom LibraryGlideModule to custom image url. The code are below:

@GlideModule
class ResizeableUrlGlideModule : LibraryGlideModule() {
    override fun registerComponents(context: Context, glide: Glide, registry: Registry) {
        registry.append(IResizeableUrl::class.java, InputStream::class.java, ResizeableModelLoaderFactory())
    }
}

class ResizeableModelLoaderFactory : ModelLoaderFactory<IResizeableUrl, InputStream> {
    override fun build(multiFactory: MultiModelLoaderFactory): ResizeableModelLoader {
        return ResizeableModelLoader(
            multiFactory.build(
                String::class.java,
                InputStream::class.java
            )
        )
    }

    override fun teardown() {}
}

class ResizeableModelLoader : ModelLoader<IResizeableUrl, InputStream> {
    private var defaultLoader: ModelLoader<String, InputStream>

    constructor(uriLoader: ModelLoader<String, InputStream>) {
        this.defaultLoader = uriLoader
    }

    override fun buildLoadData(
        model: IResizeableUrl,
        width: Int,
        height: Int,
        options: Options
    ): ModelLoader.LoadData<InputStream>? {
        model.getResizeableUrl(width, height)?.let { newUrl ->
            return defaultLoader.buildLoadData(newUrl, width, height, options)
        }
        return null
    }

    override fun handles(model: IResizeableUrl): Boolean {
        return true
    }
}

interface IResizeableUrl {
    fun getResizeableUrl(width: Int, height: Int): String?
}

class ScreenWidthUrl(url: String?, val ratio: Float = 1F) : ResizeableUrl(url) {
    override fun getResizeableUrlInternal(width: Int, height: Int): String? {
        ....
    }
}

2. Error appear when using KAPT,i can use ScreenWidthUrl like below:

Glide.with(imageView).load(ScreenWidthUrl(imageUrl)).into(view)

But after migrate to KSP,i get an error:

    com.bumptech.glide.Registry$NoModelLoaderAvailableException: Failed to find any ModelLoaders registered for model class: class com.youdao.dict.core.glide.model.UserIconUrl
        at com.bumptech.glide.load.model.ModelLoaderRegistry.getModelLoaders(ModelLoaderRegistry.java:77)
        at com.bumptech.glide.Registry.getModelLoaders(Registry.java:594)
        at com.bumptech.glide.load.engine.DecodeHelper.getLoadData(DecodeHelper.java:212)
        at com.bumptech.glide.load.engine.DecodeHelper.getCacheKeys(DecodeHelper.java:229)
        at com.bumptech.glide.load.engine.ResourceCacheGenerator.startNext(ResourceCacheGenerator.java:47)
        at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:311)
        at com.bumptech.glide.load.engine.DecodeJob.runWrapped(DecodeJob.java:277)
        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:424)
        at java.lang.Thread.run(Thread.java:920)
        at com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultPriorityThreadFactory$1.run(GlideExecutor.java:383)

3. Try to solve error I have searched without solution. So i print message in function`s body and find the diff between KAPT and KSP.

4. Discussion My app module is still using KAPT, because it using DataBinding. And ResizeableUrlGlideModule is in library module which use KSP. When library module use KAPT too, everything is ok. When library module use KSP, i got error above. Can anyone tell me how to solve this? thanks!

opLW commented 1 year ago

I have tested these case.

  1. app module uses ksp + library module used ksp
  2. app module uses ksp + library module used kapt
  3. app module uses kapt + library module used ksp
  4. app module uses kapt + library module used kapt

Only the case 3 got error above, there maybe a bug for Glide?

sjudd commented 1 year ago

Thanks for the detail! Something similar was reported in #5269

sjudd commented 1 year ago

Are you able to run kapt for the data binding processor and ksp for the glide processor? Unfortunately it's pretty painful to test this scenario.

sjudd commented 1 year ago

Ah ok I think I know why the ksp processor generates indexes in a separate package name that the java processor does not check. I guess I was thinking people would go from kapt -> ksp, but not the other way around.

sjudd commented 1 year ago

Yeah ok so we write the Indexer intermediates to a different package in KSP than in the java processor and with a different annotation. This is something we could change. However, I think it's probably better if you just use ksp at the top level for your Glide annotation processing. As far as I can tell, you should be able to do that and continue to use kapt for data binding.

Does that sound like a reasonable option?

opLW commented 1 year ago

Using kapt for databinding and ksp for Glide is useful for me. Oh, is a solution that i never been thought. Thanks for your suggest!! Whether Glide have a post or document which can help me to know more about how Glide adapt ksp.