В документации Android написано следующее:
Dispatchers.IO — этот диспетчер оптимизирован для работы с диском или сетью. Ввод-вывод вне основного потока. Примеры включают использование компонента
Room, чтение или запись файлов, а также выполнение любых
сетевых операций.
В моем приложении В некоторых случаях мне нужно прочитать файлы .json, расположенные в каталоге assets, преобразовать эти файлы (с помощью Moshi) и отобразить их на экране с помощью Jetpack Compose.
Исходя из того, что сказано в документации, я понимаю, что для такого типа операций мне следует использовать Dispatchers.IO.
В ViewModel у меня есть вот это код, который читает данный локальный файл:
@HiltViewModel
class FileViewModel @Inject constructor(
private val getFileUseCase: GetFileUseCase,
@Dispatcher(LPlusDispatchers.IO) private val ioDispatcher: CoroutineDispatcher,
) : ViewModel() {
private val _uiState = MutableStateFlow(FileUiState.Loading)
val uiState: StateFlow = _uiState.asStateFlow()
fun loadData(fileRequest: FileRequest) {
_uiState.value = FileUiState.Loading
viewModelScope.launch(ioDispatcher) {
try {
val result = getFileUseCase(fileRequest)
_uiState.value = FileUiState.Loaded(FileItemUiState(result))
} catch (error: Exception) {
_uiState.value = FileUiState.Error(ExceptionParser.getMessage(error))
}
}
}
//...
}
Это вариант использования:
class GetFileUseCase @Inject constructor(
private val fileRepository: LocalFileRepository
) {
suspend operator fun invoke(fileRequest: FileRequest): MutableList =
fileRepository.getFile(fileRequest)
}
А это код в репозитории:
override suspend fun getFile(fileRequest: FileRequest): MutableList {
val fileResponse = assetProvider.getFiles(fileRequest.fileName)
val moshi = Moshi.Builder()
.add(
PolymorphicJsonAdapterFactory.of(Content::class.java, "type")
.withSubtype(Paragraphus::class.java, "p")
.withSubtype(Rubrica::class.java, "r")
.withSubtype(Titulus::class.java, "t")
//...
)
.add(KotlinJsonAdapterFactory())
.build()
fileResponse.forEach {
if (books.contains(it.fileName)) {
it.text = moshi.adapter(Book::class.java).fromJson(it.text.toString()))
// ...
}
}
return fileResponse
}
Что меня удивляет, так это то, что при добавлении viewModelScope.launch(ioDispatcher) код выполняется постоянно. То есть, если я ставлю точку останова в коде, который ищет файлы, переданные в параметре, он постоянно останавливается в этой точке. С другой стороны, если я добавлю только viewModelScope.launch(), код будет работать должным образом, считывая файлы, переданные в параметре, только один раз.
Мой вопрос вот в чем: не обязательно ли в этом случае использовать Dispatchers.IO, хотя в документации написано использовать его для чтения файлов? Почему?
Я не знаю, изменилось ли здесь использование Jetpack Compose. Ниже я показываю использование состояния, сгенерированного в ViewModel:
@Composable
fun FileScreen(
modifier: Modifier = Modifier,
fileRequest: FileRequest,
viewModel: FileViewModel = hiltViewModel(),
)
{
viewModel.loadData(fileRequest)
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
FileScreen(modifier = modifier, uiState = uiState)
}
@Composable
fun FileScreen(
modifier: Modifier,
uiState: FileViewModel.FileUiState
)
{
when (uiState) {
FileViewModel.FileUiState.Empty -> EmptyState()
is FileViewModel.FileUiState.Error -> ErrorState()
is FileViewModel.FileUiState.Loaded -> {
uiState.itemState.allData.forEach {
Text(text = it.text)
}
}
FileViewModel.FileUiState.Loading -> LoadingState()
}
}
Подробнее здесь: https://stackoverflow.com/questions/790 ... on-android
Как правильно использовать Dispatchers.IO для чтения локальных файлов на Android? ⇐ Android
Форум для тех, кто программирует под Android
1727712407
Anonymous
В документации Android написано следующее:
[b]Dispatchers.IO[/b] — этот диспетчер оптимизирован для работы с диском или сетью. Ввод-вывод вне основного потока. Примеры включают использование компонента
Room, чтение или запись файлов, а также выполнение любых
сетевых операций.
В моем приложении В некоторых случаях мне нужно прочитать файлы .json, расположенные в каталоге assets, преобразовать эти файлы (с помощью Moshi) и отобразить их на экране с помощью Jetpack Compose.
Исходя из того, что сказано в документации, я понимаю, что для такого типа операций мне следует использовать [b]Dispatchers.IO[/b].
В ViewModel у меня есть вот это код, который читает данный локальный файл:
@HiltViewModel
class FileViewModel @Inject constructor(
private val getFileUseCase: GetFileUseCase,
@Dispatcher(LPlusDispatchers.IO) private val ioDispatcher: CoroutineDispatcher,
) : ViewModel() {
private val _uiState = MutableStateFlow(FileUiState.Loading)
val uiState: StateFlow = _uiState.asStateFlow()
fun loadData(fileRequest: FileRequest) {
_uiState.value = FileUiState.Loading
viewModelScope.launch(ioDispatcher) {
try {
val result = getFileUseCase(fileRequest)
_uiState.value = FileUiState.Loaded(FileItemUiState(result))
} catch (error: Exception) {
_uiState.value = FileUiState.Error(ExceptionParser.getMessage(error))
}
}
}
//...
}
Это вариант использования:
class GetFileUseCase @Inject constructor(
private val fileRepository: LocalFileRepository
) {
suspend operator fun invoke(fileRequest: FileRequest): MutableList =
fileRepository.getFile(fileRequest)
}
А это код в репозитории:
override suspend fun getFile(fileRequest: FileRequest): MutableList {
val fileResponse = assetProvider.getFiles(fileRequest.fileName)
val moshi = Moshi.Builder()
.add(
PolymorphicJsonAdapterFactory.of(Content::class.java, "type")
.withSubtype(Paragraphus::class.java, "p")
.withSubtype(Rubrica::class.java, "r")
.withSubtype(Titulus::class.java, "t")
//...
)
.add(KotlinJsonAdapterFactory())
.build()
fileResponse.forEach {
if (books.contains(it.fileName)) {
it.text = moshi.adapter(Book::class.java).fromJson(it.text.toString()))
// ...
}
}
return fileResponse
}
Что меня удивляет, так это то, что при добавлении viewModelScope.launch(ioDispatcher) код выполняется постоянно. То есть, если я ставлю точку останова в коде, который ищет файлы, переданные в параметре, он постоянно останавливается в этой точке. С другой стороны, если я добавлю только viewModelScope.launch(), код будет работать должным образом, считывая файлы, переданные в параметре, только один раз.
Мой вопрос вот в чем: не обязательно ли в этом случае использовать Dispatchers.IO, хотя в документации написано использовать его для чтения файлов? Почему?
Я не знаю, изменилось ли здесь использование Jetpack Compose. Ниже я показываю использование состояния, сгенерированного в ViewModel:
@Composable
fun FileScreen(
modifier: Modifier = Modifier,
fileRequest: FileRequest,
viewModel: FileViewModel = hiltViewModel(),
)
{
viewModel.loadData(fileRequest)
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
FileScreen(modifier = modifier, uiState = uiState)
}
@Composable
fun FileScreen(
modifier: Modifier,
uiState: FileViewModel.FileUiState
)
{
when (uiState) {
FileViewModel.FileUiState.Empty -> EmptyState()
is FileViewModel.FileUiState.Error -> ErrorState()
is FileViewModel.FileUiState.Loaded -> {
uiState.itemState.allData.forEach {
Text(text = it.text)
}
}
FileViewModel.FileUiState.Loading -> LoadingState()
}
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79038662/how-to-use-dispatchers-io-correctly-to-read-local-files-on-android[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия