Skip to content

Commit 6a5feb7

Browse files
authored
Merge pull request #582 from yschimke/loaders
Improve network pooling and avoid startup image fetches.
2 parents 17ffb5b + 4fa7300 commit 6a5feb7

File tree

5 files changed

+59
-28
lines changed

5 files changed

+59
-28
lines changed

app/build.gradle.kts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,6 @@ dependencies {
131131
implementation(libs.androidx.profileinstaller)
132132

133133
implementation(libs.coil.kt)
134-
implementation(libs.coil.kt.svg)
135134
}
136135

137136
// androidx.test is forcing JUnit, 4.12. This forces it to use 4.13

app/src/main/java/com/google/samples/apps/nowinandroid/NiaApplication.kt

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,33 +19,24 @@ package com.google.samples.apps.nowinandroid
1919
import android.app.Application
2020
import coil.ImageLoader
2121
import coil.ImageLoaderFactory
22-
import coil.decode.SvgDecoder
2322
import com.google.samples.apps.nowinandroid.sync.initializers.Sync
2423
import dagger.hilt.android.HiltAndroidApp
24+
import javax.inject.Inject
25+
import javax.inject.Provider
2526

2627
/**
2728
* [Application] class for NiA
2829
*/
2930
@HiltAndroidApp
3031
class NiaApplication : Application(), ImageLoaderFactory {
32+
@Inject
33+
lateinit var imageLoader: Provider<ImageLoader>
34+
3135
override fun onCreate() {
3236
super.onCreate()
3337
// Initialize Sync; the system responsible for keeping data in the app up to date.
3438
Sync.initialize(context = this)
3539
}
3640

37-
/**
38-
* Since we're displaying SVGs in the app, Coil needs an ImageLoader which supports this
39-
* format. During Coil's initialization it will call `applicationContext.newImageLoader()` to
40-
* obtain an ImageLoader.
41-
*
42-
* @see <a href="https://github.com/coil-kt/coil/blob/main/coil-singleton/src/main/java/coil/Coil.kt">Coil</a>
43-
*/
44-
override fun newImageLoader(): ImageLoader {
45-
return ImageLoader.Builder(this)
46-
.components {
47-
add(SvgDecoder.Factory())
48-
}
49-
.build()
50-
}
41+
override fun newImageLoader(): ImageLoader = imageLoader.get()
5142
}

core/network/build.gradle.kts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,7 @@ dependencies {
5151
implementation(libs.okhttp.logging)
5252
implementation(libs.retrofit.core)
5353
implementation(libs.retrofit.kotlin.serialization)
54+
55+
implementation(libs.coil.kt)
56+
implementation(libs.coil.kt.svg)
5457
}

core/network/src/main/java/com/google/samples/apps/nowinandroid/core/network/di/NetworkModule.kt

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,20 @@
1717
package com.google.samples.apps.nowinandroid.core.network.di
1818

1919
import android.content.Context
20+
import coil.ImageLoader
21+
import coil.decode.SvgDecoder
22+
import coil.util.DebugLogger
23+
import com.google.samples.apps.nowinandroid.core.network.BuildConfig
2024
import com.google.samples.apps.nowinandroid.core.network.fake.FakeAssetManager
2125
import dagger.Module
2226
import dagger.Provides
2327
import dagger.hilt.InstallIn
2428
import dagger.hilt.android.qualifiers.ApplicationContext
2529
import dagger.hilt.components.SingletonComponent
2630
import kotlinx.serialization.json.Json
31+
import okhttp3.Call
32+
import okhttp3.OkHttpClient
33+
import okhttp3.logging.HttpLoggingInterceptor
2734
import javax.inject.Singleton
2835

2936
@Module
@@ -41,4 +48,44 @@ object NetworkModule {
4148
fun providesFakeAssetManager(
4249
@ApplicationContext context: Context,
4350
): FakeAssetManager = FakeAssetManager(context.assets::open)
51+
52+
@Provides
53+
@Singleton
54+
fun okHttpCallFactory(): Call.Factory = OkHttpClient.Builder()
55+
.addInterceptor(
56+
HttpLoggingInterceptor()
57+
.apply {
58+
if (BuildConfig.DEBUG) {
59+
setLevel(HttpLoggingInterceptor.Level.BODY)
60+
}
61+
},
62+
)
63+
.build()
64+
65+
/**
66+
* Since we're displaying SVGs in the app, Coil needs an ImageLoader which supports this
67+
* format. During Coil's initialization it will call `applicationContext.newImageLoader()` to
68+
* obtain an ImageLoader.
69+
*
70+
* @see <a href="https://github.com/coil-kt/coil/blob/main/coil-singleton/src/main/java/coil/Coil.kt">Coil</a>
71+
*/
72+
@Provides
73+
@Singleton
74+
fun imageLoader(
75+
okHttpCallFactory: Call.Factory,
76+
@ApplicationContext application: Context,
77+
): ImageLoader = ImageLoader.Builder(application)
78+
.callFactory(okHttpCallFactory)
79+
.components {
80+
add(SvgDecoder.Factory())
81+
}
82+
// Assume most content images are versioned urls
83+
// but some problematic images are fetching each time
84+
.respectCacheHeaders(false)
85+
.apply {
86+
if (BuildConfig.DEBUG) {
87+
logger(DebugLogger())
88+
}
89+
}
90+
.build()
4491
}

core/network/src/main/java/com/google/samples/apps/nowinandroid/core/network/retrofit/RetrofitNiaNetwork.kt

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,8 @@ import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFact
2525
import kotlinx.serialization.ExperimentalSerializationApi
2626
import kotlinx.serialization.Serializable
2727
import kotlinx.serialization.json.Json
28+
import okhttp3.Call
2829
import okhttp3.MediaType.Companion.toMediaType
29-
import okhttp3.OkHttpClient
30-
import okhttp3.logging.HttpLoggingInterceptor
3130
import retrofit2.Retrofit
3231
import retrofit2.http.GET
3332
import retrofit2.http.Query
@@ -75,20 +74,12 @@ private data class NetworkResponse<T>(
7574
@Singleton
7675
class RetrofitNiaNetwork @Inject constructor(
7776
networkJson: Json,
77+
okhttpCallFactory: Call.Factory,
7878
) : NiaNetworkDataSource {
7979

8080
private val networkApi = Retrofit.Builder()
8181
.baseUrl(NiaBaseUrl)
82-
.client(
83-
OkHttpClient.Builder()
84-
.addInterceptor(
85-
// TODO: Decide logging logic
86-
HttpLoggingInterceptor().apply {
87-
setLevel(HttpLoggingInterceptor.Level.BODY)
88-
},
89-
)
90-
.build(),
91-
)
82+
.callFactory(okhttpCallFactory)
9283
.addConverterFactory(
9384
@OptIn(ExperimentalSerializationApi::class)
9485
networkJson.asConverterFactory("application/json".toMediaType()),

0 commit comments

Comments
 (0)