Миграция на соплины Kotlin в Android с Kotlin 1,3 - PullRequest
0 голосов
/ 24 октября 2018

Что я должен изменить в своем файле build.gradle или импортировать в классы, чтобы использовать стабильные функции сопрограмм в моем проекте Android с Kotlin 1.3?

Фрагмент о сопрограммах в моих build.gradle

implementation "org.jetbrains.kotlin:kotlin-coroutines-core:$coroutines_version" implementation "org.jetbrains.kotlin:kotlin-coroutines-android:$coroutines_version"

Конечно, я использую Android Studio 3.3 Preview

Ответы [ 2 ]

0 голосов
/ 02 ноября 2018

В build.gradle изменить библиотеку на

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1'.

Удалить, если было добавлено:

kotlin {
    experimental {
        coroutines "enable"
    }
}

При изменении кода launch на GlobalScope.launch(Dispatchers.IO) или GlobalScope.launch(Dispatchers.Main).

ОБНОВЛЕНИЕ

Пожалуйста, используйте локальный контекст сопрограммы вместо глобальной области (см., Например, http://kotlinlang.org/docs/reference/coroutines/coroutine-context-and-dispatchers.html).

Для действия

См. https://github.com/Kotlin/kotlinx.coroutines/blob/master/ui/coroutines-guide-ui.md.

Реализация CoroutineScope:

class YourActivity : AppCompatActivity(), CoroutineScope {

Добавить локальную переменную job и инициализировать ее:

private lateinit var job: Job

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    job = Job()
}

Создайте контекст сопрограммы и отмените его при уничтожении действия:

override fun onDestroy() {
    job.cancel()
    super.onDestroy()
}

override val coroutineContext: CoroutineContext
    get() = Dispatchers.Main + job

Для фрагмента (аналогично Activity)

Реализация CoroutineScope:

class YourFragment : Fragment(), CoroutineScope {

Создайте локальную переменную job и инициализируйте ее в onCreate(). (Я пытался написать private val job: Job = Job(), но столкнулся с проблемой, что в ViewPager вы создадитеFragment s и их задания. Поскольку мы отменим job в onDestroy() во время считывания в ViewPager, мы должны воссоздать задание).

private lateinit var job: Job

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    ...
    job = Job()
}

Создайте контекст сопрограммы и отмените егона фрагменте уничтожить:

override val coroutineContext: CoroutineContext
    get() = Dispatchers.Main + job // You can use different variants here. 

override fun onDestroy() {
    job.cancel()
    super.onDestroy()
}

Пример запуска

Используйте launch как обычно:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    launch {
        // Wait for result of I/O operation without blocking the main thread.
        withContext(Dispatchers.IO) {
            interactor.getCountry().let {
                countryName = it.name
            }
        }

        // Update views in the UI thread.
        country.updateCaption(countryName)
    }
}

В моем случае возникла проблема, когда я использовал запросы API с обычными обратными вызовами.launch интерьер внутри обратного вызова не был вызван.Поэтому я переписал этот код с помощью интеракторов.

0 голосов
/ 25 октября 2018

Мой товарищ по команде помог мне найти решение.Мне пришлось увеличить версию сопрограмм до 1.0.0-RC1.Для всех, кто может не знать об изменениях в использовании сопрограмм Android:

  • Мне пришлось изменить контекст сопрограммы пользовательского интерфейса на Dispatchers.Main
  • Я использовал старую экспериментальную версию сопрограмм(Может быть 0,23), поэтому для всех, кто не знает - теперь запуск не рекомендуется, и вместо этого вам следует использовать структурированный параллелизм (например, coroutineScope).
  • Теперь асинхронную функцию нельзя запускать вне области действия.

Надеюсь, я кому-нибудь помогу.Не трать время.Удачного программирования!

...