android: rework injection setup

This commit is contained in:
Harsh Shandilya 2022-07-03 21:41:44 +05:30
parent 4d78a41e49
commit bf4ddeda0a
No known key found for this signature in database
GPG key ID: 366D7BBAD1031E80
8 changed files with 83 additions and 44 deletions

View file

@ -50,6 +50,7 @@ dependencies {
implementation(libs.kotlinx.serialization.json)
implementation(libs.material.motion.core)
implementation(libs.material.motion.navigation)
implementation(libs.okhttp.loggingInterceptor)
implementation(libs.retrofit.kotlinxSerializationConverter)
implementation(libs.sqldelight.extensions.coroutines)
}

View file

@ -1,19 +1,13 @@
package dev.msfjarvis.claw.android.injection
import android.content.Context
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
import dagger.Lazy
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import dev.msfjarvis.claw.android.interceptors.NapierLoggingInterceptor
import dev.msfjarvis.claw.android.interceptors.UserAgentInterceptor
import dev.msfjarvis.claw.api.LobstersApi
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.json.Json
import okhttp3.Cache
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import retrofit2.Retrofit
@ -23,35 +17,16 @@ import retrofit2.create
@Module
@InstallIn(SingletonComponent::class)
object ApiModule {
@Provides
fun provideCache(@ApplicationContext context: Context): Cache {
return Cache(context.cacheDir, 10 * 1024 * 1024)
}
@Provides
fun provideClient(cache: Lazy<Cache>): OkHttpClient {
return OkHttpClient.Builder()
.cache(cache.get())
.addNetworkInterceptor(UserAgentInterceptor())
.addNetworkInterceptor(NapierLoggingInterceptor())
.build()
}
/**
* Using [Lazy] here is a trick I picked up from Zac Sweers, which he explained in more detail
* here: https://www.zacsweers.dev/dagger-party-tricks-deferred-okhttp-init/
*/
@Provides
fun provideRetrofit(
client: Lazy<OkHttpClient>,
json: Lazy<Json>,
client: OkHttpClient,
json: Json,
): Retrofit {
val contentType = "application/json".toMediaType()
return Retrofit.Builder()
.client(client.get())
.client(client)
.baseUrl(LobstersApi.BASE_URL)
.addConverterFactory(json.get().asConverterFactory(contentType))
.addConverterFactory(json.asConverterFactory(contentType))
.build()
}

View file

@ -0,0 +1,20 @@
package dev.msfjarvis.claw.android.injection
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import dagger.multibindings.IntoSet
import dev.msfjarvis.claw.android.network.NapierLogger
import dev.msfjarvis.claw.android.network.UserAgentInterceptor
import okhttp3.Interceptor
import okhttp3.logging.HttpLoggingInterceptor
@Module
@InstallIn(SingletonComponent::class)
interface InterceptorModule {
@Binds fun NapierLogger.bindLogger(): HttpLoggingInterceptor.Logger
@Binds @IntoSet fun UserAgentInterceptor.bindUAInterceptor(): Interceptor
}

View file

@ -0,0 +1,41 @@
package dev.msfjarvis.claw.android.injection
import android.content.Context
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import dagger.multibindings.IntoSet
import okhttp3.Cache
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
@Module
@InstallIn(SingletonComponent::class)
object OkHttpModule {
@Provides
fun provideCache(@ApplicationContext context: Context): Cache {
return Cache(context.cacheDir, 10 * 1024 * 1024)
}
@Provides
fun provideClient(
cache: Cache,
interceptors: Set<@JvmSuppressWildcards Interceptor>,
): OkHttpClient {
return OkHttpClient.Builder()
.apply {
cache(cache)
interceptors.forEach(::addNetworkInterceptor)
}
.build()
}
@Provides
@IntoSet
fun provideHttpLoggingInterceptor(logger: HttpLoggingInterceptor.Logger): Interceptor {
return HttpLoggingInterceptor(logger).setLevel(HttpLoggingInterceptor.Level.HEADERS)
}
}

View file

@ -1,13 +0,0 @@
package dev.msfjarvis.claw.android.interceptors
import io.github.aakira.napier.Napier
import okhttp3.Interceptor
import okhttp3.Response
class NapierLoggingInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
Napier.d(tag = "LobstersApi") { "${request.method}: ${request.url}" }
return chain.proceed(request)
}
}

View file

@ -0,0 +1,12 @@
package dev.msfjarvis.claw.android.network
import io.github.aakira.napier.Napier
import javax.inject.Inject
import okhttp3.logging.HttpLoggingInterceptor
/** Implementation of [HttpLoggingInterceptor.Logger] backed by [Napier]. */
class NapierLogger @Inject constructor() : HttpLoggingInterceptor.Logger {
override fun log(message: String) {
Napier.d(tag = "LobstersApi") { message }
}
}

View file

@ -1,10 +1,12 @@
package dev.msfjarvis.claw.android.interceptors
package dev.msfjarvis.claw.android.network
import dev.msfjarvis.claw.android.BuildConfig
import javax.inject.Inject
import okhttp3.Interceptor
import okhttp3.Response
class UserAgentInterceptor : Interceptor {
/** An OkHttp [Interceptor] that adds a recognizable User-Agent header to all network requests. */
class UserAgentInterceptor @Inject constructor() : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
return chain.proceed(
chain

View file

@ -63,6 +63,7 @@ material_motion-core = { module = "io.github.fornewid:material-motion-compose-co
material_motion-navigation = { module = "io.github.fornewid:material-motion-compose-navigation", version.ref = "material_motion" }
multiplatform-paging = "io.github.kuuuurt:multiplatform-paging:0.4.7"
napier = "io.github.aakira:napier:2.6.1"
okhttp-loggingInterceptor = "com.squareup.okhttp3:logging-interceptor:3.14.9"
retrofit-kotlinxSerializationConverter = "com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:0.8.0"
retrofit-lib = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" }
retrofit-mock = { module = "com.squareup.retrofit2:retrofit-mock", version.ref = "retrofit" }