17
17
package com.google.samples.apps.nowinandroid.core.network.demo
18
18
19
19
import JvmUnitTestDemoAssetManager
20
+ import android.os.Build.VERSION.SDK_INT
21
+ import android.os.Build.VERSION_CODES.M
20
22
import com.google.samples.apps.nowinandroid.core.network.Dispatcher
21
23
import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.IO
22
24
import com.google.samples.apps.nowinandroid.core.network.NiaNetworkDataSource
@@ -28,6 +30,7 @@ import kotlinx.coroutines.withContext
28
30
import kotlinx.serialization.ExperimentalSerializationApi
29
31
import kotlinx.serialization.json.Json
30
32
import kotlinx.serialization.json.decodeFromStream
33
+ import java.io.BufferedReader
31
34
import javax.inject.Inject
32
35
33
36
/* *
@@ -39,24 +42,39 @@ class DemoNiaNetworkDataSource @Inject constructor(
39
42
private val assets : DemoAssetManager = JvmUnitTestDemoAssetManager ,
40
43
) : NiaNetworkDataSource {
41
44
42
- @OptIn(ExperimentalSerializationApi ::class )
43
45
override suspend fun getTopics (ids : List <String >? ): List <NetworkTopic > =
44
- withContext(ioDispatcher) {
45
- assets.open(TOPICS_ASSET ).use(networkJson::decodeFromStream)
46
- }
46
+ getDataFromJsonFile(TOPICS_ASSET )
47
47
48
- @OptIn(ExperimentalSerializationApi ::class )
49
48
override suspend fun getNewsResources (ids : List <String >? ): List <NetworkNewsResource > =
50
- withContext(ioDispatcher) {
51
- assets.open(NEWS_ASSET ).use(networkJson::decodeFromStream)
52
- }
49
+ getDataFromJsonFile(NEWS_ASSET )
53
50
54
51
override suspend fun getTopicChangeList (after : Int? ): List <NetworkChangeList > =
55
52
getTopics().mapToChangeList(NetworkTopic ::id)
56
53
57
54
override suspend fun getNewsResourceChangeList (after : Int? ): List <NetworkChangeList > =
58
55
getNewsResources().mapToChangeList(NetworkNewsResource ::id)
59
56
57
+ /* *
58
+ * Get data from the given JSON [fileName].
59
+ */
60
+ @OptIn(ExperimentalSerializationApi ::class )
61
+ private suspend inline fun <reified T > getDataFromJsonFile (fileName : String ): List <T > =
62
+ withContext(ioDispatcher) {
63
+ assets.open(fileName).use { inputStream ->
64
+ if (SDK_INT <= M ) {
65
+ /* *
66
+ * On API 23 (M) and below we must use a workaround to avoid an exception being
67
+ * thrown during deserialization. See:
68
+ * https://github.com/Kotlin/kotlinx.serialization/issues/2457#issuecomment-1786923342
69
+ */
70
+ inputStream.bufferedReader().use(BufferedReader ::readText)
71
+ .let (networkJson::decodeFromString)
72
+ } else {
73
+ networkJson.decodeFromStream(inputStream)
74
+ }
75
+ }
76
+ }
77
+
60
78
companion object {
61
79
private const val NEWS_ASSET = " news.json"
62
80
private const val TOPICS_ASSET = " topics.json"
0 commit comments