Glide: How to use Glide 4 generated API correctly both in app module and library module?

Created on 14 Sep 2017  路  16Comments  路  Source: bumptech/glide


Glide Version: 4.1.1


Issue details:
screen shot 2017-09-14 at 18 19 50
I create a new project named app, and then create a new module named mylibrary. I include glide4 dependency both in my app module and library module followed by doc
app/build.gradlecode:

apply plugin: 'com.android.application'

android {
    ...
}

dependencies {
    compile project(":mylibrary")
    compile 'com.github.bumptech.glide:glide:4.1.1'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.1.1'
}

mylibrary/build.gradle code:

apply plugin: 'com.android.library'

android {
    ...
}

dependencies {
    compile 'com.github.bumptech.glide:glide:4.1.1'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.1.1'
}

Then I create classes extends AppGlideModule both in app module and library module in order to use GlideApp (Glide generated API) in these two modules.

package com.myapp.app;

@GlideModule
public class MyAppModule extends AppGlideModule {
}

```java
package com.myapp.mylibrary;

@GlideModule
public final class MyLibraryModule extends AppGlideModule {
}

But after running the demo, crash occurs when I call `GlideApp.with(this)` in `MainActivity` belongs to app module.
crash logcat:

E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.ClassCastException: com.myapp.mylibrary.GlideRequests cannot be cast to com.myapp.app.GlideRequests
at com.laoyouzhibo.a.GlideApp.with(GlideApp.java:87)

I found `GeneratedAppGlideModuleImpl` and `GeneratedRequestManagerFactory` are duplicated inside app module and library module. IDE reminds me `duplicate class found in the file.`
<img width="374" alt="screen shot 2017-09-14 at 18 25 35" src="https://user-images.githubusercontent.com/3355843/30427646-1bd9fca8-9983-11e7-932a-606d8928a7f4.png">

If I make `MyLibraryModule` extend `LibraryGlideModule`, I cannot find GlideApp in my library module.
```java
@GlideModule
public final class MyLibraryModule extends LibraryGlideModule {
}

This is a simple demonstration for my situation. My application module and a couple of library modules depend on glide.

documentation question

Most helpful comment

If you're writing a library for others to use, yes you should not use the generated API and therefore GlideApp won't be available.

If you simply have multiple library components within a single application then it can make sense to add your AppGlideModule in a single subcomponent and have the rest depend on it.

All 16 comments

I've tried to clarify this here: http://bumptech.github.io/glide/doc/generatedapi.html#availability.

If you're just using Libraries internally as part of your application, you can define another internal library project that contains only your AppGlideModule and Glide configuration and then depend on that module in your applications and other internal libraries.

I miss this sentence.

The generated API is only available for applications for now.

Thanks for your solution.Maybe I'll choose using RequestOptions in my libraries.

Yup, you can definitely just use RequestOptions, it's just somewhat less convenient.

so we just do not use GlideApp in library module?

If you're writing a library for others to use, yes you should not use the generated API and therefore GlideApp won't be available.

If you simply have multiple library components within a single application then it can make sense to add your AppGlideModule in a single subcomponent and have the rest depend on it.

I have add AppGlideModule in my subcomponent.
My app depends on subcomponent. I add LibraryGlideModule to app module. But LibraryGlideModule is not working now.
Method
override fun registerComponents(context: Context, glide: Glide, registry: Registry)
Is not called now.

@dakishin I'm facing this issue too, did you solve it?
I need Glide only for library module, don't want to provide it to module users

if you want to use glide only for module you can define dependency in gradle implementation '...glide..'
It should work.

There is no answer for my bug. Why this issue is closed?
I want use glide in module and customise it in main app. It is impossible now.

@dakishin It doesn't work because it requires that every application will extends from AppGlideModule,
If application which uses my module doesn't implement
@GlideModule class MyGlideModule : AppGlideModule()

my library is not loaded.
@GlideModule class SdkGlideModule : LibraryGlideModule()
my library is SDK module, I don't want to request every app to extend AppGlideModule...

Only AppGlideModule generates stub classes with GlideApp class.
Library must have AppGlideModule to get access to GlideApp.
App witch uses this lib also have access to GlideApp by default. App build.gradle just have
implementation project(':lib_with_glide')

And this is ok. There is no problem here. App jus have additional class GlideApp. But you cant configure GlideApp (this is my bug about) in this case.

In general. As I understand android. All .class files from libs and app go to single(or multiple) dex file during merge stage. You can get problems if you app also have glide dependency.

Also AppGlideModule should be only one in your program.

@pavelaizen - @dakishin is correct you need to use a LibraryGlideModule and apps will have to add their own AppGlideModule. It's (hopefully) not a hugely complicated step for them to take and we need a single signal to generate the API (or see my response below :)).

@dakishin - It is actually possible to generate separate APIs for libraries and applications. The problem is that it's likely to be super confusing for app developers. We could differentiate by package name, but then you're going to get com.mypackage.GlideApp and com.library.GlideApp every time you try to autocomplete and the APIs aren't going to match. You could get around this a bit with renames, but it seems like the added confusion for application developers isn't worth the convenience to library developers given that RequestOptions works fine as is.

I have one LibraryGlideModule in my idea library module. I need to use GlideApp inside library.
So two glideApp one is for library use, one is for whole application is acceptable? Or inject the GlideApp from Application to my library module?

Edit:
if create two AppGlideModule in Application and library,
Multiple dex files define Lcom/bumptech/glide/GeneratedAppGlideModuleImpl;
will happen when make project. But the app still can build success.

I meet this problem too, and Finally I just only user AppGlideModule in app module.
And the submodule just uses normal Glide.with instead of GlideApp.with.
It works for me now, it's enough for using .

I miss this sentence.

The generated API is only available for applications for now.

Thanks for your solution.Maybe I'll choose using RequestOptions in my libraries.

I used Glide in my personal library and released through jfrog, which is quite simple:

object ImageBindingAdapter {
    @JvmStatic
    @BindingAdapter(value = ["android:src", "fallbackImageUrl"], requireAll = false)
    fun setImageUrl(view: ImageView, src: String?, fallbackImageUrl: String?, ...) {
        val requestOptions = RequestOptions().apply {
            ....
        }
        Glide.with(view.context)
                .load(src)
                .error(Glide.with(view.context).load(fallbackImageUrl))
                .apply(requestOptions)
                .into(view)
    }
}

however, I got the following issue when I use this library in my application:

Caused by: java.lang.ClassNotFoundException: Didn't find class "com.bumptech.glide.request.RequestOptions" on path: DexPathList[[zip file "/data/app/....

I tried

implementation ("com.github.bumptech.glide:glide:$4.10.0@aar") {
    transitive = true
}

also updated the proguard rules

-keep class com.bumptech.** {*;}
-keepclassmembers class com.bumptech.** {*;}

also added mavenCentral() in repositories.

The issue was still there. Anyone can help me out how to use glide in the library? Thanks
@sjudd

@vincgao have you managed to pull out a solution for this?

I am running into the same scenario. Could you please help with this? thanks

@vincgao

package com.myapp.app;

@GlideModule
public class MyAppModule extends AppGlideModule {
}

Removing MyAppModule implementation from app module will fix the issue.
So the app module can use GlideApp generated in mylibrary

Note: make sure below Glide dependencies should be added in both app module & mylibrary module

dependencies {
compile 'com.github.bumptech.glide:glide:4.1.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.1.1'
}

Was this page helpful?
0 / 5 - 0 ratings