File.createTempFile() показывает «Неправильный вызов метода блокировки» в CoroutineWorker

#android #kotlin-coroutines #android-workmanager

#Android #kotlin-сопрограммы #android-workmanager

Вопрос:

У меня есть следующий класс, который реализует WorkManager

 @HiltWorker
class LexemeWorker @AssistedInject constructor(
    @Assisted appContext: Context,
    @Assisted workerParams: WorkerParameters,
    private val firebaseStorage: FirebaseStorage,
) : CoroutineWorker(appContext, workerParams) {

    companion object {
        const val Progress = "Progress"
        private const val delayDuration = 1L
    }

    override suspend fun doWork(): Result {

        val storageRef = firebaseStorage.reference

        val pathReference = storageRef.child("lexeme.zip")

        val file = File.createTempFile("lexeme", ".zip")

        val path = pathReference.getFile(file).await()

        var progress = 0.0

        while (progress < 100) {
            progress = (100.0 * path.bytesTransferred) / path.totalByteCount
            setProgress(workDataOf(Progress to progress))
            delay(delayDuration)

            if (path.error != null) {
                return Result.failure()
            }
        }
        
        return Result.success()
    }
}
 

Я не знаю, по какой причине android studio показывает сообщение "Inapropriate blocking method call" on createTempFile . Я также пытался поместить все внутрь withContext(Dispatchers.IO) , но без шансов решить проблему. Как избавиться от этого предупреждения?

Правка1: наоборот withContext(Dispatchers.IO)

 override suspend fun doWork(): Result = withContext(Dispatchers.IO) {

    ....

    val file = File.createTempFile("lexeme", ".zip")

    ...

    while (progress < 100) {
        progress = (100.0 * path.bytesTransferred) / path.totalByteCount
        setProgress(workDataOf(Progress to progress))
        delay(delayDuration)

        if (path.error != null) {
            Result.failure()
        }
    }

    Result.success()
}
 

Комментарии:

1. Может быть, вам следует выполнить этот код в потоке? Но почему вы хотите уже создать файл? Не будет GetFile(file) создавать файл. Вам нужно только настроить экземпляр файла, чтобы GetFile знал, где создать файл.. Не создавать файл уже. Хм .. или это класс файла из Firebase, а не классический класс файла ввода-вывода Java?

2. «Я также попытался поместить все внутри с помощью context(диспетчеры. Ввод-вывод), но без шансов решить проблему» — это предупреждение чрезмерно усердно. Тем не менее, я не видел, чтобы он отображался при использовании withContext(Dispatchers.IO) . Не могли бы вы отредактировать свой вопрос и показать, как вы его использовали?

3. @CommonsWare отредактировал мой вопрос. Спасибо

4. Похоже, это ошибка .

Ответ №1:

Не уверен, почему возникает это предупреждение, возможно, потому File.createTempFile() , что функция выдает IOException . Чтобы избавиться от этого предупреждения, мы можем обернуть File.createTempFile() функцию в runCatching :

 ...

val file: File? = runCatching {
    File.createTempFile("lexeme", ".zip")
}.getOrNull()

...