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

How to inject OkHttpClient instance #2002

Open
b95505017 opened this Issue Jun 3, 2017 · 11 comments

Comments

Projects
None yet
7 participants
@b95505017
Copy link
Contributor

b95505017 commented Jun 3, 2017

According to OkHttp jdoc:

OkHttpClients should be shared

I notice that the OkHttp integration module generate a OkHttpClient internal instance. It would be better to allow us inject the singleton OkHttpClient within our application.

@gajicm93

This comment has been minimized.

Copy link

gajicm93 commented Jun 13, 2017

Glide.with(context).getRegistry().replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory(CLIENT));

@TWiStErRob

This comment has been minimized.

Copy link
Collaborator

TWiStErRob commented Jun 13, 2017

See also: http://bumptech.github.io/glide/doc/configuration.html#applications
It's probably better to have a GlideModule then statically messing with the registry somewhere .with(context) may imply expensive initialization that you're not expecting at that point.

@b95505017

This comment has been minimized.

Copy link
Contributor

b95505017 commented Jun 13, 2017

I know the getRegistry().replace(...) way, but I want to use the default OkHttpLibraryGlideModule with my application OkHttpClient instance injection.

@TWiStErRob

This comment has been minimized.

Copy link
Collaborator

TWiStErRob commented Jun 13, 2017

You can't use the default integration Glide module, as there's no way to propagate your custom client to that module. That's why you need to write your own App module, exclude the library module and register the factory yourself with your custom client.

@sjudd

This comment has been minimized.

Copy link
Member

sjudd commented Jun 15, 2017

Yes getRegistry() will probably start throwing an exception if it's modified outside of a GlideModule in the near future.

@b95505017

This comment has been minimized.

Copy link
Contributor

b95505017 commented Jun 15, 2017

@sjudd So is there a recommend way to share my OkHttpClient instance with Glide 4?

@sjudd

This comment has been minimized.

Copy link
Member

sjudd commented Jun 15, 2017

You can pass it into Glide in an AppGlideModule or LibraryGlideModule. Accessing it in the Module will require either dependency injection or holding your client in a singleton somewhere.

For modules, see http://bumptech.github.io/glide/doc/configuration.html#appglidemodule

@dptsolutions

This comment has been minimized.

Copy link

dptsolutions commented Jul 2, 2017

After going through the links and everyone's comments here, I've come up with this example that should allow me to use the OkHttp3 integration library, exclude the @GlideModule that comes with the integration library, and provide my own OkHttpClient instance from my Dagger 2 ApplicationComponent - Glide4OkHttp3Dagger2Module.java. Perhaps it could be an example for the documentation?

That said, this being my first time using Glide, this method of getting the component into Glide seems clunky. I kind of wish I could just intialize a @Singleton scoped GlideApp instance in my ApplicationModule and just inject that baby through Dagger 2, like anything else I need.

@TWiStErRob

This comment has been minimized.

Copy link
Collaborator

TWiStErRob commented Jul 2, 2017

@dptsolutions that looks ok to me.

Note that you cannot have a @Provides @Singleton GlideApp glide() because GlideApp doesn't have instance methods. You'll need @Provides @FragmentScope GlideRequests glide(Fragment frag) { return GlideApp.with(frag); }.

In your GlideModule you can try to make it a bit nicer with something like:

public interface ApplicationComponent {
    void inject(MyAppGlideModule glide);
}
public class MyAppGlideModule extends AppGlideModule {
    @Inject OkHttpClient client;
    public MyAppGlideModule() {
        MyApplication.getInstance().getApplicationComponent().inject(this);
    }
    ... new OkHttpUrlLoader.Factory(client)

but your current approach is just as valid: the component interface is there so that you can pull objects out of the dependency graph.

@ar-g

This comment has been minimized.

Copy link

ar-g commented Sep 15, 2017

I completely agree with @dptsolutions that setting up Glide this way is not obvious at all.

@UsherBaby

This comment has been minimized.

Copy link

UsherBaby commented Feb 3, 2018

This is my project demo

AppComponent

@Singleton
@Component(modules = [(AppModule::class)])
interface AppComponent : AndroidInjector<App> {

    fun glideComponentBuilder(): GlideComponent.Builder

    @Component.Builder
    abstract class Builder : AndroidInjector.Builder<App>()
}

@Singleton
@Module(includes = [(AndroidSupportInjectionModule::class), (AppBinder::class)],
        subcomponents = [(GlideComponent::class)])
class AppModule {

    @Singleton
    @Provides
    fun provideOkHttpClient(): OkHttpClient {
        return OkHttpClient.Builder().build()
    }
}

Glide Config

@Excludes(OkHttpLibraryGlideModule::class)
@GlideModule
class NewOkHttpLibraryGlideModule : AppGlideModule() {
    @Inject
    lateinit var okHttpClient: OkHttpClient

    init {
        App.instance!!.appComponent()
                .glideComponentBuilder()
                .glideModule(GlideDaggerModule())
                .build()
                .inject(this)
    }

    override fun isManifestParsingEnabled() = false

    override fun registerComponents(context: Context, glide: Glide, registry: Registry) {
        super.registerComponents(context, glide, registry)
        registry.replace(GlideUrl::class.java, InputStream::class.java, OkHttpUrlLoader.Factory(okHttpClient))
    }
}


@Subcomponent(modules = [(GlideDaggerModule::class)])
interface GlideComponent {

    fun inject(newOkHttpLibraryGlideModule: NewOkHttpLibraryGlideModule)

    @Subcomponent.Builder
    interface Builder {

        fun glideModule(glideModule: GlideDaggerModule): Builder

        fun build(): GlideComponent
    }
}

@Module
class GlideDaggerModule
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment