LoginSignup
5
2

More than 5 years have passed since last update.

(メモ)Glide v4のAppGlideModuleにOkHttpClientをInjectする

Posted at

前提

既にDagger2によるDIをかっちり組んでOkHttpClientをInjectしているプロジェクトで、新たにGlide v4を導入する場合。

参考にしたコード

How to inject OkHttpClient instance · Issue #2002 · bumptech/glide

サンプルコード

リポジトリ

issueではApplicationをSingletonにしてインスタンスを参照するような解決方法でしたが、どうせregisterComponentsでapplicationContextを突っ込むならそこでInjectすればよかろうと考えました。

AppGlideModule用にSubcomonentを定義し、DaggerApplication派生のApplicationクラスにinjectメソッドを追加しました。

新たに追加する分

AppGlideModuleはregisterComponentsに前述の処理を加えた以外はセオリー通りです。

AppGlideModule

CustomAppGlideModule.kt
@GlideModule(glideName = "CustomGlideApp")
class CustomAppGlideModule : AppGlideModule() {
    @Inject
    lateinit var okHttpClient: OkHttpClient

    override fun isManifestParsingEnabled() = false

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

Subcomponent

SubcomponentにはBuilderを定義しています。

GlideComponent.kt
@Subcomponent
interface GlideComponent {
    fun inject(appGlideModule: CustomAppGlideModule)

    @Subcomponent.Builder
    interface Builder {
        fun build(): GlideComponent
    }
}

既存のものに変更する分

AppModule

AppModuleはsubcomponentsアノテーションに先述のSubcomponentを追加するだけです。

AppModule.kt
@Module(subcomponents = [GlideComponent::class])
internal object AppModule {
    // 以下は既存のものそのままなので略
}

AppComponent

AppComponentにはSubcomponentのBuilderを生成するメソッドを追加します。

AppComponent.kt
@Singleton
@Component(modules = [
    AndroidSupportInjectionModule::class,
    AppModule::class,
    MainActivityBuilder::class,
    ViewModelModule::class
])
interface AppComponent : AndroidInjector<App> {
    @Component.Builder
    interface Builder {
        @BindsInstance
        fun application(application: Application): Builder

        fun build(): AppComponent
    }

    override fun inject(application: App)

    // 以下新しく追加
    fun glideComponentBuilder(): GlideComponent.Builder
}

Application

ApplicationはInjectメソッドを追加します。

App.kt
class App : DaggerApplication() {
    override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
        return DaggerAppComponent.builder()
                .application(this)
                .build()
    }

    override fun onCreate() {
        super.onCreate()
        if (BuildConfig.DEBUG) {
            Timber.plant(Timber.DebugTree())
        }
    }

    // 以下新しく追加
    fun inject(appGlideModule: CustomAppGlideModule) {
        (applicationInjector() as AppComponent).glideComponentBuilder().build().inject(appGlideModule)
    }
}

後はViewで利用するだけです。

MainActivity.kt
class MainActivity : DaggerAppCompatActivity() {
    @Inject
    lateinit var viewModelFactory: ViewModelProvider.Factory

    private lateinit var viewModel: MainViewModel
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        CustomGlideApp.with(this)
                .load("https://qiita-image-store.s3.amazonaws.com/0/21354/profile-images/1473683312")
                .into(binding.image)

        viewModel = ViewModelProviders.of(this, viewModelFactory).get(MainViewModel::class.java)
    }
}

サンプルではQiitaの私のアイコンを読み込ませました。不気味です。

サンプル

5
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2