В этом разделе рассматривается отмена корутин и тайм-ауты.
Отмена выполнения корутин
В долго работающем приложении вам может понадобиться детальное управление фоновыми корутинами. Например, пользователь может закрыть страницу, которая запускала корутину, из-за чего её результат больше не нужен, и её действие можно отменить. Функция launch возвращает Job , которую можно использовать для отмены запущенной корутины.
val job = launch < repeat(1000) < i ->println(«job: 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.»)
You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-cancel-01.kt). —>
Этот код выведет следующее:
job: I’m sleeping 0 . job: I’m sleeping 1 . job: I’m sleeping 2 . main: I’m tired of waiting! main: Now I can quit.
Как только главная функция вызывает job.cancel , мы больше не видим какого-либо вывода с другой корутины, потому что она была отменена. Существует также cancelAndJoin функция-расширение Job , которая объединяет вызовы cancel и join.
Только так можно ограничить время работы любого приложения на Android | Ставим таймер в приложениях!
Отмена кооперативна
Отмена корутин кооперативна. Код корутины должен взаимодействовать, чтобы его можно было отменить. Все suspend-функции в kotlinx.coroutines — отменяемые. Они проверяют отмену корутины, и в случае отмены выбрасывают исключение CancellationException . Однако, если корутина работает над вычислениями и не проверяет на отмену, то её нельзя отменить, как это происходит, например, здесь:
val startTime = System.currentTimeMillis() val job = launch(Dispatchers.Default) < var nextPrintTime = startTime var i = 0 while (i < 5) < // computation loop, just wastes CPU // print a message twice a second if (System.currentTimeMillis() >= nextPrintTime) < println(«job: I’m sleeping $. «) 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.»)
You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-cancel-02.kt). —>
Запустив этот код, вы увидите как корутина продолжает выводить на экран «I’m sleeping» даже после отмены, пока job не завершится после пяти итераций.
Делаем код с вычислениями отменяемым
Есть два способа сделать вычислительный код отменяемым. Первый – периодически вызвать suspend-функцию, которая проверяет, активна ли корутина. Для этого хорошо подходит функция yield . Другой — явно проверять статус отмены. Попробуем этот подход.
val startTime = System.currentTimeMillis() val job = launch(Dispatchers.Default) < var nextPrintTime = startTime var i = 0 while (isActive) < // cancellable computation loop // print a message twice a second if (System.currentTimeMillis() >= nextPrintTime) < println(«job: I’m sleeping $. «) 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.»)
You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-cancel-03.kt). —>
Что делать если телефон вылетает из приложений?
Как вы можете увидеть, теперь цикл отменяется. isActive — это extension-параметр, доступный внутри корутины, благодаря объекту CoroutineScope .
Закрытие ресурсов при помощи finally
Отменяемые suspend-функции при отмене выбрасывают исключение CancellationException , которое может быть обработано обычным путём. Например, выражение try <. >finally <. >и Kotlin-функция use обыкновенно выполняют свои функции при завершении (отмене) корутин.
val job = launch < try < repeat(1000) < i ->println(«job: I’m sleeping $i . «) delay(500L) > > finally < println(«job: I’m running finally») >> 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.»)
You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-cancel-04.kt). —>
И join , и cancelAndJoin ожидают завершения всех финальных стадий, поэтому приведённый выше пример даёт такой вывод:
job: I’m sleeping 0 . job: I’m sleeping 1 . job: I’m sleeping 2 . main: I’m tired of waiting! job: I’m running finally main: Now I can quit.
Запуск неотменяемого блока
Любая попытка использовать suspend-функцию в блоке finally предыдущего примера приводит к CancellationException , потому что корутина, выполняющая этот код, отменена. Обычно это не проблема, так как все нормально работающие операции закрытия (закрытие файла, отмена Job или закрытие любого вида канала) обычно не блокируются и не требуют каких-либо suspend-функций. Однако в редких случаях, когда вам нужно приостановить работу отмененной корутины, вы можете обернуть соответствующий код в withContext(NonCancellable) <. >с использованием функции withContext и контекста NonCancellable , как показано в следующем примере:
val job = launch < try < repeat(1000) < i ->println(«job: I’m sleeping $i . «) delay(500L) > > finally < withContext(NonCancellable) < println(«job: I’m running finally») delay(1000L) println(«job: And I’ve just delayed for 1 sec because I’m non-cancellable») >> > 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.»)
You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-cancel-05.kt). —>
Тайм-аут
Самая очевидная практическая причина отменить выполнение корутины — время её выполнения превысило некоторый тайм-аут. Хотя можно вручную отслеживать обращение к соответствующему Job и запускать отдельную корутину для отмены отслеживаемой после тайм-аута, есть готовая к использованию функция withTimeout , которая делает это. Посмотрите на следующий пример:
withTimeout(1300L) < repeat(1000) < i ->println(«I’m sleeping $i . «) delay(500L) > >
You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-cancel-06.kt). —>
Этот код выведет следующее:
I’m sleeping 0 . I’m sleeping 1 . I’m sleeping 2 . Exception in thread «main» kotlinx.coroutines.TimeoutCancellationException: Timed out waiting for 1300 ms
Исключение TimeoutCancellationException , создаваемое withTimeout , является подклассом CancellationException . Мы никогда раньше не видели его трассировку стека, напечатанную на консоли. Это потому, что внутри отмененной корутины CancellationException считается нормальной причиной её завершения. Однако в этом примере мы использовали withTimeout прямо внутри функции main .
Поскольку отмена является лишь исключением, все ресурсы закрываются в обычном порядке. Вы можете обернуть код с тайм-аутом в блоке try <. >catch (e: TimeoutCancellationException) <. >, если вам нужно сделать какое-то дополнительное действие специально для любого тайм-аута или использовать функцию withTimeoutOrNull . Она похожа на withTimeout , но возвращает null по тайм-ауту вместо создания исключения.
val result = withTimeoutOrNull(1300L) < repeat(1000) < i ->println(«I’m sleeping $i . «) delay(500L) > «Done» // will get cancelled before it produces this result > println(«Result is $result»)
You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-cancel-07.kt). —>
Теперь ошибки при выполнении этой корутины не будет:
I’m sleeping 0 . I’m sleeping 1 . I’m sleeping 2 . Result is null
Асинхронный тайм-аут и ресурсы
Событие тайм-аута в withTimeout является асинхронным по отношению к коду, работающему в его блоке, и может произойти в любое время, даже прямо перед возвратом из блока тайм-аута. Имейте это в виду, если вы открываете или приобретаете ресурс внутри блока, который необходимо закрыть или освободить за пределами блока.
Например, здесь мы имитируем закрываемый ресурс с помощью класса Resource , который просто отслеживает, сколько раз он был создан путем увеличения счетчика acquired и уменьшения этого счетчика из его функции close . Давайте запустим много корутин с небольшим таймаутом, попробуем получить этот ресурс изнутри блока withTimeout после небольшой задержки и освободить его извне.
var acquired = 0 class Resource < init < acquired++ >// Acquire the resource fun close() < acquired— >// Release the resource > fun main() < runBlocking < repeat(100_000) < // Launch 100K coroutines launch < val resource = withTimeout(60) < // Timeout of 60 ms delay(50) // Delay for 50 ms Resource() // Acquire a resource and return it from withTimeout block >resource.close() // Release the resource > > > // Outside of runBlocking all coroutines have completed println(acquired) // Print the number of resources still acquired >
You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-cancel-08.kt). —>
Если вы запустите приведенный выше код, вы увидите, что он не всегда выводит ноль, хотя это может зависеть от таймингов вашей машины, вам может потребоваться настроить тайм-ауты в этом примере, чтобы действительно увидеть ненулевые значения.
Note, that incrementing and decrementing `acquired` counter here from 100K coroutines is completely safe, > since it always happens from the same main thread. More on that will be explained in the chapter > on coroutine context. —>
Обратите внимание, что увеличение и уменьшение счетчика acquired здесь из 100 000 корутин совершенно безопасно, так как это всегда происходит из одного и того же основного потока. Подробнее об этом будет рассказано в главе о контексте корутин.
Чтобы обойти эту проблему, вы можете сохранить ссылку на ресурс в переменной, а не возвращать ее из блока withTimeout .
runBlocking < repeat(100_000) < // Launch 100K coroutines launch < var resource: Resource? = null // Not acquired yet try < withTimeout(60) < // Timeout of 60 ms delay(50) // Delay for 50 ms resource = Resource() // Store a resource to the variable if acquired >// We can do something else with the resource here > finally < resource?.close() // Release the resource if it was acquired >> > > // Outside of runBlocking all coroutines have completed println(acquired) // Print the number of resources still acquired
You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-cancel-09.kt). —>
Этот пример всегда выводит 0, а ресурсы не утекают.
Источник: kotlinlang.ru
Удаление системных приложений на телефоне Vivo
Полезное
В процессе пользования смартфоном в его памяти появляется множество различных приложений, при помощи которых юзеры решают свои проблемы. Необходимый софт возможно скачать из официальных магазинов или на сторонних сайтах в интернете. Однако, первоначально на новых китайских гаджетах присутствует системный софт. Это набор предустановленных утилит, не связанных с операционной системой, но представляющих сложность в удалении.
К их числу относятся, например, сервисы Google и проч. Такие программы занимают место в памяти смартфона и редко приносят действительную пользу. В связи с этим пользователи задумываются над тем, возможно ли удаление системных приложений на телефоне Vivo. Сделать это вполне реально, однако, стоит заранее подготовиться к трате времени и использованию дополнительных средств. Наиболее безопасные и одновременно эффективные способы удаления предустановленных утилит мы рассмотрим в статье.
Навигация по статье
- Зачем удалять встроенные приложения?
- Как удалить стандартные приложения на телефоне Vivo
- Использование ADB AppControl
- Полное удаление программ
- Видео-инструкция
- FAQ
Зачем удалять встроенные приложения?
Прежде чем перейти к инструкции, как удалить приложение с телефона Vivo, стоит уточнить причины, по которым пользователи прибегают к данной процедуре. Так, на сегодняшний день выделяется две предпосылки к ликвидации предустановленного софта:
- недостаток внутренней памяти;
- частое появление ненужных уведомлений.
Всего две причины действительно заставляют пользователей задуматься над избавлением от системного софта. А как это сделать правильно – мы рассмотрим ниже.
Как удалить стандартные приложения на телефоне Vivo
Говоря о том, как убрать ненужные приложения со смартфона Vivo, стоит отметить, что самый простой способ в данном случае – отключение этих приложений. Делается это с помощью встроенных функций гаджета. Пользователю потребуется:
- Открыть «Настройки» и перейти в раздел с приложениями.
- Выбрать ненужную системную программу, открыть ее и кликнуть «Отключить».
Егор Борисов
Техноблогер, тестирую гаджеты, помогаю в настройке и оптимизации смартфонов и носимых устройств.
Задать вопрос
Перед началом операции рекомендую внимательно ознакомится с требованиями и списком нужных файлов.
Такими действиями удастся заблокировать функционирование предустановленной утилиты. В дальнейшем она перестанет расходовать ресурсы устройства, но при необходимости ее вполне возможно включить по той же схеме.
Использование ADB AppControl
Широко распространенная утилита ADB AppControl позволяет быстро и безопасно отключить системные приложения. Она особенно хорошо подходит для владельцев китайских версий смартфонов, так как с утилитами, подписанными иероглифами, самостоятельно разобраться сложно.
Для работы с ADB AppControl потребуется использовать компьютер/ноутбук.
Рассмотрим инструкцию на примере с удалением приложения с непонятным китайским наименованием. Так, последовательность действий здесь следующая:
- Скачать «просмотрщик пакетов приложений» — Package Name Viewer.
- Открыть установленную программу и найти в списке приложение, которое требуется отключить.
- Выполнить длительное нажатие по наименованию найденной утилиты и скопировать название пакета или запомнить его.
- Скачать на компьютер программу ADB AppControl с официального сайта.
- Открыть на ПК загруженный софт и подключить смартфон к компьютеру привычным способом (с активной отладкой по USB).
- Дождаться синхронизации и согласиться с предложениями ADB AppControl.
- Найти в списке название пакета приложения, подлежащего отключению (ввести скопированный фрагмент в поиск или пролистать весь перечень вручную), и кликнуть по нему.
- В нижнем углу экрана ПК выбрать «Disable» («Отключить») и нажать на одноименную кнопку рядом.
- Согласиться с предупреждением об опасности, кликнув «Ок» в появившемся окне.
После проделанных действий отключенное приложение пропадет из меню и перестанет присылать пользователю уведомления. Однако, при этом оно продолжит автоматически обновляться, а смартфон будет работать в привычном режиме.
Программа ADB AppControl доступна только для ПК, на смартфонах же ее аналогами являются Activity Launcher, Shortcutmaker и т.д., однако, они менее функциональны.
Полное удаление программ
Описанные выше способы максимально лояльны, и никакого вреда смартфону они не причиняют. К тому же, такие варианты оставляют пользователю возможность активировать отключенное приложение при необходимости. Однако, существует метод, позволяющий навсегда избавиться от ненужного софта.
Так, полностью удалить приложение с телефона Виво удастся таким образом:
- Установить на компьютер Android Debug Bridge (ADB) с официального сайта.
- Скачать на смартфон утилиту App Inspector.
- Подключить телефон к ПК.
- Выполнить распаковку архива ADB в корневую папку диска.
- Запустить командную строку (ввести в поиске Windows «cmd.exe» и запустить от имени администратора).
- Обработать запросы «cd c:/adb», «adb devices», «adb shell», поочередно нажимая после ввода каждого из них клавишу «Enter».
- Активировать App Inspector на мобильном гаджете.
- Выбрать наименование ненужной предустановленной программы.
- Скопировать наименование в пункте «Package name».
- В командной строке на ПК ввести запрос «pm uninstall -k —user 0 *Package Name*» (вставив вместо «Package Name» наименование пакета системного приложения для удаления).
- Нажать кнопку «Enter» на клавиатуре компьютера.
Как и в случае с отключением предустановленных программ, после пройденных этапов ненужный софт исчезнет из меню гаджета. Однако, вместе с этим на него не будут приходить обновления.
Данный способ не требует использования прав суперпользователя.
Видео-инструкция
FAQ
Почему системные приложения лучше отключать, нежели удалять?
Полное удаление системных приложений в большинстве случаев негативно сказывается на работоспособности гаджета. Пользователь может по незнанию стереть из памяти смартфона утилиту, принимающую участие в функционировании ОС. Что же касается отключения, при нем приложения пропадают с главного экрана и не присылают уведомлений, однако, обновляются и выполняют нужные системе функции.
Какие приложения можно смело отключать, не опасаясь за работоспособность системы?
Исчерпывающий перечень таких утилит представлен на форуме 4PDA.
Система требует войти в учетную запись Vivo при скачивании ADB AppControl, но аккаунта не существует. Что делать?
Такая ситуация встречается нередко при установке стороннего софта. А решается она путем отключения проверки учетной записи. Для этого потребуется пройти путь: «Настройки» — «Безопасность и конфиденциальность» — «Дополнительные настройки безопасности» — «Установка приложений» — отключить аутентификацию установки.
Какие смартфоны возможно подключить к ADB AppControl?
Данная программа работает совершенно со всеми моделями гаджетов Vivo.
Бороться с системными приложениями – не самое легкое задание. Однако, справиться с ненужным софтом, отправляющим лишние уведомления и занимающим место в памяти устройства, вполне возможно. Делается это как при помощи сторонних программ, так и без них. Поэтому пользователю предоставляется неплохой ассортимент способов удаления системных утилит. А инструкции с правильной последовательностью действий представлены в нашей статье, благодаря чему ошибиться в проведении процедуры не удастся.
Поделиться
Егор Борисов
Техноблогер, автор нескольких проектов об умных устройствах. Пишу статьи по правильной настройке телефонов Vivo и оптимизации оболочки Funtouch OS для новичков.
Источник: vivohelp.com