Skip to content

Commit 32e988a

Browse files
authored
Merge pull request #224 from caarmen/use-injected-io-dispatcher
Provide an ioDispatcher via dagger. Use it to read the license text.
2 parents 200e829 + 6885152 commit 32e988a

File tree

6 files changed

+105
-35
lines changed

6 files changed

+105
-35
lines changed

app/src/main/kotlin/ca/rmen/android/poetassistant/about/LicenseActivity.kt

Lines changed: 13 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,13 @@ package ca.rmen.android.poetassistant.about
2222
import android.content.Context
2323
import android.content.Intent
2424
import android.os.Bundle
25-
import android.util.Log
2625
import androidx.activity.compose.setContent
2726
import androidx.activity.enableEdgeToEdge
28-
import androidx.annotation.WorkerThread
27+
import androidx.activity.viewModels
2928
import androidx.appcompat.app.AppCompatActivity
29+
import androidx.compose.runtime.collectAsState
3030
import ca.rmen.android.poetassistant.Constants
31-
import ca.rmen.android.poetassistant.dagger.DaggerHelper
3231
import ca.rmen.android.poetassistant.theme.AppTheme
33-
import java.io.BufferedReader
34-
import java.io.IOException
35-
import java.io.InputStreamReader
3632

3733
class LicenseActivity : AppCompatActivity() {
3834
companion object {
@@ -52,38 +48,20 @@ class LicenseActivity : AppCompatActivity() {
5248
override fun onCreate(savedInstanceState: Bundle?) {
5349
super.onCreate(savedInstanceState)
5450
enableEdgeToEdge()
51+
val licenseViewModel: LicenseViewModel by viewModels()
5552
val title = intent.getStringExtra(EXTRA_TITLE)!!
5653
val licenseFile = intent.getStringExtra(EXTRA_LICENSE_TEXT_ASSET_FILE)!!
57-
val threading = DaggerHelper.getMainScreenComponent(this).getThreading()
58-
threading.execute(
59-
{ readFile(licenseFile) },
60-
{
61-
setContent {
62-
AppTheme {
63-
LicenseScreen(
64-
title = title,
65-
licenseText = it,
66-
onBack = onBackPressedDispatcher::onBackPressed
67-
)
68-
}
69-
}
70-
})
71-
}
72-
73-
@WorkerThread
74-
private fun readFile(fileName: String): String {
75-
76-
try {
77-
BufferedReader(InputStreamReader(assets.open(fileName))).use {
78-
val builder = StringBuilder()
79-
it.forEachLine { line ->
80-
builder.append(line).append('\n')
81-
}
82-
return builder.toString()
54+
licenseViewModel.readLicenseText(licenseFile)
55+
setContent {
56+
val licenseText = licenseViewModel.licenseText.collectAsState()
57+
AppTheme {
58+
LicenseScreen(
59+
title = title,
60+
licenseText = licenseText.value,
61+
onBack = onBackPressedDispatcher::onBackPressed
62+
)
8363
}
84-
} catch (e: IOException) {
85-
Log.e(TAG, "Couldn't read license file $fileName: ${e.message}", e)
86-
return ""
8764
}
8865
}
66+
8967
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright (c) 2025 - present Carmen Alvarez
3+
*
4+
* This file is part of Poet Assistant.
5+
*
6+
* Poet Assistant is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* Poet Assistant is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with Poet Assistant. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
package ca.rmen.android.poetassistant.about
20+
21+
import android.app.Application
22+
import android.util.Log
23+
import androidx.lifecycle.AndroidViewModel
24+
import androidx.lifecycle.viewModelScope
25+
import ca.rmen.android.poetassistant.Constants
26+
import ca.rmen.android.poetassistant.dagger.DaggerHelper
27+
import kotlinx.coroutines.CoroutineDispatcher
28+
import kotlinx.coroutines.flow.MutableStateFlow
29+
import kotlinx.coroutines.flow.asStateFlow
30+
import kotlinx.coroutines.launch
31+
import java.io.IOException
32+
import javax.inject.Inject
33+
34+
class LicenseViewModel(private val application: Application) :
35+
AndroidViewModel(application) {
36+
37+
companion object {
38+
private val TAG = Constants.TAG + LicenseViewModel::class.java.simpleName
39+
}
40+
41+
init {
42+
DaggerHelper.getMainScreenComponent(application).inject(this)
43+
}
44+
45+
@Inject
46+
lateinit var ioDispatcher: CoroutineDispatcher
47+
48+
private val _licenseText = MutableStateFlow("")
49+
val licenseText = _licenseText.asStateFlow()
50+
51+
fun readLicenseText(fileName: String) {
52+
viewModelScope.launch(ioDispatcher) {
53+
val contents = readFile(fileName)
54+
_licenseText.value = contents
55+
}
56+
}
57+
58+
private fun readFile(fileName: String): String {
59+
try {
60+
return application.assets.open(fileName).bufferedReader().use { it.readText() }
61+
} catch (e: IOException) {
62+
Log.e(TAG, "Couldn't read license file $fileName: ${e.message}", e)
63+
return ""
64+
}
65+
}
66+
}

app/src/main/kotlin/ca/rmen/android/poetassistant/dagger/AppComponent.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ package ca.rmen.android.poetassistant.dagger
2222
import ca.rmen.android.poetassistant.Favorites
2323
import ca.rmen.android.poetassistant.PoemAudioExport
2424
import ca.rmen.android.poetassistant.Threading
25+
import ca.rmen.android.poetassistant.about.LicenseViewModel
2526
import ca.rmen.android.poetassistant.main.MainActivity
2627
import ca.rmen.android.poetassistant.main.dictionaries.ResultListAdapterFactory
2728
import ca.rmen.android.poetassistant.main.dictionaries.ResultListHeaderViewModel
@@ -48,6 +49,7 @@ import ca.rmen.android.poetassistant.wotd.WotdEntryViewModel
4849
import ca.rmen.android.poetassistant.wotd.WotdLiveData
4950
import dagger.Component
5051
import dagger.Subcomponent
52+
import kotlinx.coroutines.CoroutineDispatcher
5153
import javax.inject.Singleton
5254

5355
@Singleton
@@ -64,6 +66,7 @@ interface AppComponent {
6466
fun getFavorites(): Favorites
6567
fun getSettingsPrefs(): SettingsPrefs
6668
fun getThreading(): Threading
69+
fun getIODispatcher(): CoroutineDispatcher
6770
fun getResultListAdapterFactory() : ResultListAdapterFactory
6871
}
6972

@@ -75,6 +78,7 @@ interface AppComponent {
7578
fun injectDict(resultListViewModel: ResultListViewModel<DictionaryEntry>)
7679
fun inject(rtEntry: RTEntryViewModel)
7780
fun inject(resultListHeaderViewModel: ResultListHeaderViewModel)
81+
fun inject(licenseViewModel: LicenseViewModel)
7882
fun inject(readerViewModel: ReaderViewModel)
7983
fun inject(poemAudioExport: PoemAudioExport)
8084
fun inject(rhymerLiveData: RhymerLiveData)

app/src/main/kotlin/ca/rmen/android/poetassistant/dagger/ThreadingModule.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import ca.rmen.android.poetassistant.CoroutineThreading
2323
import ca.rmen.android.poetassistant.Threading
2424
import dagger.Module
2525
import dagger.Provides
26+
import kotlinx.coroutines.CoroutineDispatcher
2627
import kotlinx.coroutines.Dispatchers
2728
import javax.inject.Singleton
2829

@@ -31,4 +32,9 @@ class ThreadingModule {
3132
@Provides
3233
@Singleton
3334
fun providesThreading() : Threading = CoroutineThreading(Dispatchers.Default, Dispatchers.Main)
35+
36+
37+
@Provides
38+
@Singleton
39+
fun providesIODispatcher(): CoroutineDispatcher = Dispatchers.IO
3440
}

app/src/sharedTest/kotlin/ca/rmen/android/poetassistant/dagger/TestThreadingModule.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ import ca.rmen.android.poetassistant.InstrumentationThreading
2323
import ca.rmen.android.poetassistant.Threading
2424
import dagger.Module
2525
import dagger.Provides
26+
import kotlinx.coroutines.CoroutineDispatcher
27+
import kotlinx.coroutines.ExperimentalCoroutinesApi
28+
import kotlinx.coroutines.test.UnconfinedTestDispatcher
2629
import javax.inject.Singleton
2730

2831
@Module
@@ -31,4 +34,9 @@ class TestThreadingModule {
3134
@Provides
3235
@Singleton
3336
fun providesThreading(): Threading = InstrumentationThreading()
37+
38+
@OptIn(ExperimentalCoroutinesApi::class)
39+
@Provides
40+
@Singleton
41+
fun providesIODispatcher(): CoroutineDispatcher = UnconfinedTestDispatcher()
3442
}

app/src/test/kotlin/ca/rmen/android/poetassistant/dagger/JunitThreadingModule.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,19 @@ import ca.rmen.android.poetassistant.JunitThreading
2323
import ca.rmen.android.poetassistant.Threading
2424
import dagger.Module
2525
import dagger.Provides
26+
import kotlinx.coroutines.CoroutineDispatcher
27+
import kotlinx.coroutines.ExperimentalCoroutinesApi
28+
import kotlinx.coroutines.test.UnconfinedTestDispatcher
2629
import javax.inject.Singleton
2730

2831
@Module
2932
class JunitThreadingModule {
3033
@Provides
3134
@Singleton
3235
fun providesThreading() : Threading = JunitThreading()
36+
37+
@OptIn(ExperimentalCoroutinesApi::class)
38+
@Provides
39+
@Singleton
40+
fun providesIODispatcher(): CoroutineDispatcher = UnconfinedTestDispatcher()
3341
}

0 commit comments

Comments
 (0)