Skip to content

Commit 1cc71f7

Browse files
MBL-2144 Fix concurrency crash when preloading images (#2241)
* Patch to fix concurrency crash * Match BackingFragment * ktlint * Make copy of list so that we don't reference mutable list that could be cleared
1 parent 680c6be commit 1cc71f7

File tree

4 files changed

+40
-34
lines changed

4 files changed

+40
-34
lines changed

app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/AddOnsScreen.kt

+16-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.kickstarter.ui.activities.compose.projectpage
22

3+
import android.content.Context
34
import android.content.res.Configuration
45
import androidx.compose.foundation.background
56
import androidx.compose.foundation.layout.Box
@@ -26,7 +27,7 @@ import androidx.compose.ui.Modifier
2627
import androidx.compose.ui.platform.LocalContext
2728
import androidx.compose.ui.res.stringResource
2829
import androidx.compose.ui.tooling.preview.Preview
29-
import coil.ImageLoader
30+
import coil.Coil
3031
import coil.request.ImageRequest
3132
import com.kickstarter.R
3233
import com.kickstarter.libs.Environment
@@ -115,18 +116,7 @@ fun AddOnsScreen(
115116
).toString()
116117
} ?: ""
117118

118-
// Preload add ons images asynchronously
119-
val imageLoader = ImageLoader.Builder(context)
120-
.crossfade(true)
121-
.build()
122-
for (reward in addOns) {
123-
reward.image()?.let {
124-
val request = ImageRequest.Builder(context)
125-
.data(reward.image()?.full())
126-
.build()
127-
imageLoader.enqueue(request)
128-
}
129-
}
119+
preloadImages(context, addOns)
130120

131121
Box(
132122
modifier = Modifier.fillMaxSize(),
@@ -337,3 +327,16 @@ fun AddOnsScreen(
337327
}
338328
}
339329
}
330+
331+
private fun preloadImages(context: Context, rewards: List<Reward>) {
332+
val rewardsIterator = rewards.iterator()
333+
while (rewardsIterator.hasNext()) {
334+
val reward = rewardsIterator.next()
335+
reward.image()?.let {
336+
val request = ImageRequest.Builder(context)
337+
.data(reward.image()?.full())
338+
.build()
339+
Coil.imageLoader(context).enqueue(request)
340+
}
341+
}
342+
}

app/src/main/java/com/kickstarter/ui/fragments/BackingFragment.kt

+5-7
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import androidx.fragment.app.Fragment
2323
import androidx.fragment.app.viewModels
2424
import androidx.recyclerview.widget.LinearLayoutManager
2525
import androidx.recyclerview.widget.RecyclerView
26-
import coil.ImageLoader
26+
import coil.Coil
2727
import coil.request.ImageRequest
2828
import com.kickstarter.R
2929
import com.kickstarter.databinding.FragmentBackingBinding
@@ -580,16 +580,14 @@ class BackingFragment : Fragment() {
580580
}
581581

582582
private fun preloadImages(rewards: List<Reward>) {
583-
// Preload reward images asynchronously
584-
val imageLoader = ImageLoader.Builder(requireContext())
585-
.crossfade(true)
586-
.build()
587-
for (reward in rewards) {
583+
val rewardsIterator = rewards.iterator()
584+
while (rewardsIterator.hasNext()) {
585+
val reward = rewardsIterator.next()
588586
reward.image()?.let {
589587
val request = ImageRequest.Builder(requireContext())
590588
.data(reward.image()?.full())
591589
.build()
592-
imageLoader.enqueue(request)
590+
Coil.imageLoader(requireContext()).enqueue(request)
593591
}
594592
}
595593
}

app/src/main/java/com/kickstarter/ui/fragments/RewardsFragment.kt

+18-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.kickstarter.ui.fragments
22

3+
import android.content.Context
34
import android.os.Bundle
45
import android.util.Pair
56
import android.view.LayoutInflater
@@ -9,17 +10,19 @@ import androidx.appcompat.app.AlertDialog
910
import androidx.compose.foundation.lazy.rememberLazyListState
1011
import androidx.compose.runtime.LaunchedEffect
1112
import androidx.compose.runtime.getValue
13+
import androidx.compose.ui.platform.LocalContext
1214
import androidx.compose.ui.platform.ViewCompositionStrategy
1315
import androidx.fragment.app.Fragment
1416
import androidx.fragment.app.viewModels
1517
import androidx.lifecycle.compose.collectAsStateWithLifecycle
16-
import coil.ImageLoader
18+
import coil.Coil
1719
import coil.request.ImageRequest
1820
import com.kickstarter.R
1921
import com.kickstarter.databinding.FragmentRewardsBinding
2022
import com.kickstarter.libs.Environment
2123
import com.kickstarter.libs.utils.extensions.getEnvironment
2224
import com.kickstarter.libs.utils.extensions.reduce
25+
import com.kickstarter.models.Reward
2326
import com.kickstarter.ui.activities.compose.projectpage.RewardCarouselScreen
2427
import com.kickstarter.ui.compose.designsystem.KSTheme
2528
import com.kickstarter.ui.compose.designsystem.KickstarterApp
@@ -71,18 +74,7 @@ class RewardsFragment : Fragment() {
7174
val indexOfBackedReward = rewardSelectionUIState.initialRewardIndex
7275
val rewards = shippingUIState.filteredRw
7376

74-
// Preload reward images asynchronously
75-
val imageLoader = ImageLoader.Builder(context)
76-
.crossfade(true)
77-
.build()
78-
for (reward in rewards) {
79-
reward.image()?.let {
80-
val request = ImageRequest.Builder(context)
81-
.data(reward.image()?.full())
82-
.build()
83-
imageLoader.enqueue(request)
84-
}
85-
}
77+
preloadImages(LocalContext.current, rewards)
8678

8779
val project = projectData.project()
8880
val backing = projectData.backing()
@@ -128,6 +120,19 @@ class RewardsFragment : Fragment() {
128120
}
129121
}
130122

123+
private fun preloadImages(context: Context, rewards: List<Reward>) {
124+
val rewardsIterator = rewards.iterator()
125+
while (rewardsIterator.hasNext()) {
126+
val reward = rewardsIterator.next()
127+
reward.image()?.let {
128+
val request = ImageRequest.Builder(context)
129+
.data(reward.image()?.full())
130+
.build()
131+
Coil.imageLoader(context).enqueue(request)
132+
}
133+
}
134+
}
135+
131136
private fun createDialog() {
132137
context?.let { context ->
133138
dialog = AlertDialog.Builder(context, R.style.AlertDialog)

app/src/main/java/com/kickstarter/viewmodels/usecases/GetShippingRulesUseCase.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ class GetShippingRulesUseCase(
148148
loading = isLoading,
149149
selectedShippingRule = defaultShippingRule,
150150
error = errorMessage,
151-
filteredRw = filteredRewards
151+
filteredRw = filteredRewards.toList()
152152
)
153153
)
154154
}

0 commit comments

Comments
 (0)