Отменить загрузку файла (дооснащение), начатую с сопрограммы kotlin android

Я пытаюсь избавиться от RxJava2 в своем проекте и заменить его сопрограммами kotlin. 90% моего кода RxJava больше не существует, но я все еще не могу заменить один сетевой запрос. Пользователь может отправить фотографию на серверную часть в моем приложении (запрос данных из нескольких частей с использованием модификации). Пользователь также может отменить загрузку фотографии, если она еще не была загружена. С помощью RxJava я смог сохранить объект Disposable запроса на загрузку, и если он еще не удален, я мог бы удалить его, если пользователь нажал кнопку отмены загрузки. В результате этого действия также был отменен сетевой запрос. Таким образом, мы могли сэкономить некоторый пользовательский трафик и заряд батареи. Можно ли добиться такой же логики с помощью сопрограмм kotlin? В официальных документах написано, что отмена сопрограмм является кооперативной и нам нужна некоторая функция приостановки в цикле (или между отправкой частей файла), чтобы остановить сопрограмму. Так ли это, когда RxJava - лучший выбор, или я что-то пропустил?

1
0
1 433
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если вы используете модернизацию для своих сетевых вызовов, вы можете добавить их адаптер вызова сопрограмм из здесь.

Вы отменяете работающую часть сопрограммы, отменяя ее работу. Например, если вы используете launch для запуска своей сопрограммы, она возвращает объект Job, который можно отменить.

val job = launch {
        repeat(1000) { i ->
            println("I'm sleeping $i ...")
            delay(500L)
        }
    }
    delay(1300L) // delay a bit
    println("main: I'm tired of waiting!")
    job.cancel() // cancels the job
    job.join() // waits for job's completion 
    println("main: Now I can quit.")

Если вы не используете модернизацию и используете другую библиотеку, вы можете получить isActive внутри своей сопрограммы и отменить запрос из своей библиотеки.

fun main(args: Array<String>) = runBlocking<Unit> {
    val startTime = System.currentTimeMillis()
    val job = launch {
        var nextPrintTime = startTime
        var i = 0
        while (isActive) { // cancellable computation loop
            // print a message twice a second
            if (System.currentTimeMillis() >= nextPrintTime) {
                println("I'm sleeping ${i++} ...")
                nextPrintTime += 500L
            }
        }
    }
    delay(1300L) // delay a bit
    println("main: I'm tired of waiting!")
    job.cancelAndJoin() // cancels the job and waits for its completion
    println("main: Now I can quit.")
}

Большое спасибо! Адаптер вызова сопрограмм - это именно то, что мне нужно! Но что касается второй части ответа (об isActive): я думаю, что это не сработает. Потому что у меня нет цикла или другого места, где я мог бы проверить свойство isActive сопрограммы. Модернизация обрабатывает частичную загрузку файлов, и я не нашел никаких обратных вызовов, которые могли бы дать возможность проверить isActive во время загрузки. В любом случае еще раз спасибо!

Sergey 29.05.2018 09:33

Без проблем! Вы уверены, что модификация не отменяет вызов запроса OkHttp? Я не вижу здесь разницы между rx и сопрограммами, поэтому, если отмена (удаление в rx) работает, она должна работать и в сопрограммах.

Adib Faramarzi 30.05.2018 09:55

Да, проверял дважды. Отмена сопрограммы не отменяет запрос на загрузку дооснащения. Разница между rx и сопрограммой точна в адаптере вызова модификации. Одноразовый, который я использую для отмены запроса на модернизацию, был создан адаптером вызова rxjava retrofit. Вот почему этот одноразовый предмет может повлиять на запрос на модернизацию. Вы можете увидеть это здесь: ссылка на сайт. Метод public void dispose() имеет строку call.cancel. То же самое, что и адаптер вызова сопрограмм.

Sergey 31.05.2018 15:05

Это странно, потому что это отменяет загрузку. Возможно, вы могли бы сообщить о проблеме в репозиторий адаптера. Хотя их репозиторий уже заявляет, что это экспериментальная функция, поэтому я не удивлюсь, если они добавят ее в будущем выпуске. Также я не думаю, что было бы так сложно создать свой собственный. Вы можете преобразовать код из Rx-кода в стиль «сопрограммы». В любом случае, удачи!

Adib Faramarzi 31.05.2018 17:13

Есть ли другой способ отменить запрос на модернизацию без «адаптера Kotlin Coroutine»?

yoonhok 31.10.2018 10:51

Другие вопросы по теме