Я пытаюсь избавиться от RxJava2 в своем проекте и заменить его сопрограммами kotlin. 90% моего кода RxJava больше не существует, но я все еще не могу заменить один сетевой запрос. Пользователь может отправить фотографию на серверную часть в моем приложении (запрос данных из нескольких частей с использованием модификации). Пользователь также может отменить загрузку фотографии, если она еще не была загружена. С помощью RxJava я смог сохранить объект Disposable запроса на загрузку, и если он еще не удален, я мог бы удалить его, если пользователь нажал кнопку отмены загрузки. В результате этого действия также был отменен сетевой запрос. Таким образом, мы могли сэкономить некоторый пользовательский трафик и заряд батареи. Можно ли добиться такой же логики с помощью сопрограмм kotlin? В официальных документах написано, что отмена сопрограмм является кооперативной и нам нужна некоторая функция приостановки в цикле (или между отправкой частей файла), чтобы остановить сопрограмму. Так ли это, когда RxJava - лучший выбор, или я что-то пропустил?
Если вы используете модернизацию для своих сетевых вызовов, вы можете добавить их адаптер вызова сопрограмм из здесь.
Вы отменяете работающую часть сопрограммы, отменяя ее работу. Например, если вы используете 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.")
}
Без проблем! Вы уверены, что модификация не отменяет вызов запроса OkHttp? Я не вижу здесь разницы между rx и сопрограммами, поэтому, если отмена (удаление в rx) работает, она должна работать и в сопрограммах.
Да, проверял дважды. Отмена сопрограммы не отменяет запрос на загрузку дооснащения. Разница между rx и сопрограммой точна в адаптере вызова модификации. Одноразовый, который я использую для отмены запроса на модернизацию, был создан адаптером вызова rxjava retrofit. Вот почему этот одноразовый предмет может повлиять на запрос на модернизацию. Вы можете увидеть это здесь: ссылка на сайт. Метод public void dispose() имеет строку call.cancel. То же самое, что и адаптер вызова сопрограмм.
Это странно, потому что это отменяет загрузку. Возможно, вы могли бы сообщить о проблеме в репозиторий адаптера. Хотя их репозиторий уже заявляет, что это экспериментальная функция, поэтому я не удивлюсь, если они добавят ее в будущем выпуске. Также я не думаю, что было бы так сложно создать свой собственный. Вы можете преобразовать код из Rx-кода в стиль «сопрограммы». В любом случае, удачи!
Есть ли другой способ отменить запрос на модернизацию без «адаптера Kotlin Coroutine»?
Большое спасибо! Адаптер вызова сопрограмм - это именно то, что мне нужно! Но что касается второй части ответа (об isActive): я думаю, что это не сработает. Потому что у меня нет цикла или другого места, где я мог бы проверить свойство isActive сопрограммы. Модернизация обрабатывает частичную загрузку файлов, и я не нашел никаких обратных вызовов, которые могли бы дать возможность проверить isActive во время загрузки. В любом случае еще раз спасибо!