В настоящее время я разрабатываю постоянную библиотеку для Android в Котлине. В моем коде я должен обрабатывать файловые операции (чтение, запись и т.д.), Которые я хотел бы выполнять асинхронно для повышения производительности. Я думал, что смогу сделать это с новой функцией сопрограммы Kotlin 1.3
GlobalScope.launch {
writeFileAsync(file, bytes)
}
private suspend fun writeFileAsync(file: File, bytes: ByteArray) {
try {
file.writeBytes(bytes)
} catch (e: Exception) {
throw PersistenceException(e)
}
}
Допустим, я нахожусь в ситуации, когда пользователь изменил объект, который теперь сохраняется с помощью приведенного выше кода, и он закрывает приложение до завершения сопрограммы. Конечно, я не хочу останавливать сопрограмму из-за потери данных, но здесь все в порядке или я пропускаю сопрограмму?
Я также не уверен, как заблокировать все другие операции (возможно, из других потоков или процессов) для этого файла во время выполнения сопрограммы, поэтому, если у вас есть идеи для этого, пожалуйста, дайте мне знать.
Код, который вы написали, вообще не использует приостановку сопрограмм. Он просто передает блок кода в общий пул потоков по умолчанию, для которого вам не нужны сопрограммы. Вы также можете написать
ForkJoinPool.commonPool().submit {
file.writeBytes(bytes)
}
и вам не нужна зависимость от сопрограмм.
Однако, если вы хотите дождаться завершения операции ввода-вывода и выполнить некоторые операции с графическим интерфейсом, сопрограммы помогут вам. Ты можешь написать
this.launch {
withContext(Dispatchers.IO) {
file.writeBytes(bytes)
}
updateGui()
}
Однако это не помешает пользователю закрыть приложение во время выполнения операций. Что еще один уровень сложности и для его достижения, вы должны более глубоко отделить операции от вашей деятельности, WorkManager
кажется самым современным выбором.
Используйте WorkManager, чтобы выполнять свою работу в фоновом режиме, когда приложение может быть прекращено.
Во-первых, код, который вы выполняете в сопрограмме, не является более производительным. Это, вероятно, даже немного менее производительным. Но это более одновременно.
Во-вторых, если пользователь завершает работу приложения, все его потоки будут закрыты. Поскольку сопрограммы основаны на пуле потоков, они также будут остановлены. Если вы хотите, чтобы что-то продолжало работать в фоновом режиме, используйте что-то вроде Сервиса.
В-третьих, если вы хотите получить блокировку файла, используйте FileLock
FileLock
. Я прочитал документацию и нахожу этот пункт запутанным: блокировки файлов проводятся от имени всей виртуальной машины Java. Они не подходят для управления доступом к файлу несколькими потоками в одной виртуальной машине. Разве это не проблема для моего варианта использования?