Android Coroutine не заканчивается - PullRequest
0 голосов
/ 10 мая 2019

У меня есть код, где я лениво обновляю пользовательский интерфейс, используя процедуры kotlin.

Когда я помещаю некоторый код внутрь GlobalScope.async, выполняются только первые несколько строк, а остальная часть кода не


class MyFragment : Fragment(), CoroutineScope {

    private lateinit var masterJob: Job
    override val coroutineContext: CoroutineContext
        get() = Dispatchers.Main + masterJob

   override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
           GlobalScope.async(coroutineContext) {
            api.fetchOrders()
            configureOrders(view!!)

            // Some code here ... 
        }
   }

Например, в приведенном выше коде код после комментария не выполняется. И если я поменяю код над комментарием на приведенный выше, он не будет выполнен.

Что мне не хватает?

Ответы [ 4 ]

0 голосов
/ 13 мая 2019

Пара вещей:

  1. Ваш фрагмент является областью действия, но вы все еще используете GlobalScope.Dispatchers.Main + masterJob полностью игнорируется
  2. Если вы будете использовать ваш fragScope, в зависимости от реализации api.fetchOrders, ваше приложение может зависнуть, потому что вы все еще находитесь в главном потоке
  3. Похоже, выне заинтересованы в результате, поэтому не используйте Deferred
  4. Если async - это то, что вы хотите, вы должны позвонить await
0 голосов
/ 10 мая 2019

Код неверен, потому что ваш контекст сопрограммы выполняется в главном потоке с этим ключевым словом Dispatchers.Main при инициализации контекста сопрограммы. Если вы хотите выполнять вызовы API, пожалуйста, измените на Dispatchers.IO.

Я предполагаю, что api.fetchOrders() не может быть запущен в главном потоке. Кроме того, вам нужно дождаться ответа с ключевым словом .await():

val yourData = api.fetchOrders().await(), который вернет то, что находится внутри вашего Deferred типа. Например, если это Deferred<ArrayList>, он возвращает ArrayList после вызова метода await().

Примечание .

Если вы вызываете это await () в контексте этой сопрограммы, я полагаю, что у вас должна появиться ошибка, подобная NetworkOnMainThreadException

0 голосов
/ 10 мая 2019

Я выяснил, в чем проблема, код работал, но он вызывал исключение, которое не было видно в трассировке стека (не знаю почему).

Когда я изменил GlobalScope.async на GlobalScope.launch начал работать

0 голосов
/ 10 мая 2019

Когда у вас есть асинхронный метод, который что-то возвращает, он асинхронный, и проблема в том, что выполняются только первые строки метода, потому что вы не ожидаете завершения метода с ключевым словом await.

Что-то нуждается в значении, возвращаемом функцией, и принудительно завершает функцию, если только вы не используете await, тогда оно должно ждать завершения функции.

...