#android #kotlin #kotlin-coroutines #android-context
Вопрос:
В моей службе мне нужно обратиться к onStartCommand
некоторым методам, которые требуют withContext(Dispatchers.IO)
вместо CoroutineScope(Dispatchers.IO)
этого, например:
- url = URL(покемон.Изображение ссылки)
- url.openConnection().getInputStream()
- fOut= Поток вывода файла(файл)
- Фут.смыть()
- fOut.закрыть()
Но Suspend function 'withContext' should be called only from a coroutine or another suspend function
. Так что если onStartCommand
не может быть функцией приостановки, потому что она переопределена и withContext
не может быть вызвана сопрограммой из-за Inappropriate blocking method call
методов
val url = URL(pokemon.linkImage)
val iS = url.openConnection().getInputStream()
Как я могу решить эту проблему?
Моя команда OnStart ():
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
//create the directory on internal storage that will contains all pokemon images
val path = applicationContext.filesDir.absolutePath
val dirName = "/pokeimg"
val dir = File(path, dirName)
if(!dir.exists())
dir.mkdir()
CoroutineScope(Dispatchers.IO).launch {
//get the list of pokemon when they are loaded from repository
val listOfPokemon =
PersistenceSingletonRepository.getInstance(applicationContext).getListOfPokemon()
//download all the image for each pokemon in the list, but only if the image is
//not present in the directory
for(pokemon in listOfPokemon) {
val imageName = "${pokemon.name}.png"
val file = File("${dir.absolutePath}/$imageName")
//check if image not exists on internal storage and if is not an official-artwork
//images that aren't official-artwork has less quality so don't resize
if(!file.exists()) {
//download img
val url = URL(pokemon.linkImage)
val iS = url.openConnection().getInputStream()
val opts = BitmapFactory.Options()
if (!Utils.isBadImage(pokemon.linkImage)) {
//request a smaller image
opts.inSampleSize = 2
}
val bitmap = BitmapFactory.decodeStream(iS, null, opts)
val fOut= FileOutputStream(file)
bitmap?.compress(Bitmap.CompressFormat.PNG, 100, fOut)
fOut.flush()
fOut.close()
}
}
stopSelf()
}
return START_NOT_STICKY
}
Комментарии:
1. «это требует
withContext(Dispatchers.IO)
взаменCoroutineScope(Dispatchers.IO)
» — что это значит? Тебе нужноCoroutineScope
откуда-то. ЧтоCoroutineScope
вы собираетесь использовать?2. URL(pokemon. linkImage) получаю предупреждение «Неуместный вызов метода блокировки», когда я использую его в сопрограмме(Dispatchers.IO). Поэтому мне нужно использовать withContext(Диспетчеры. IO) вместо сопрограммы(Dispatchers.IO)
3. @CommonsWare Для открытого подключения к URL-адресу требуется поток, который не является основным потоком. Поэтому я использовал сопрограмму(Диспетчеры. IO) , но я получаю предупреждение «Неуместный вызов метода блокировки»
Ответ №1:
Вы можете смело игнорировать это предупреждение, известно, что оно имеет много ложных срабатываний. Вы запустили сопрограмму в диспетчере ввода-вывода, которая предназначена для блокировки вызовов.
С другой стороны, запуск чего-либо с помощью специального CoroutineScope
приложения, у которого нет родителя и привязки к жизненному циклу, обычно является неправильным. Вы должны уважать жизненный цикл службы и отменить свою сопрограмму onDestroy
. Смотрите, например, здесь.
Комментарии:
1. Это предупреждение исходит от проверок IDE, не так ли?
2. Да, это не ошибка компилятора.