Как перенести Kotlin с 1.2 на Kotlin 1.3.0 с последующим использованием async, UI и bg в функции докладчика - PullRequest
0 голосов
/ 02 ноября 2018

Я использую шаблон MVP для проекта Kotlin. У меня есть класс докладчика:

import com.google.gson.Gson
import kotlinx.coroutines.experimental.android.UI
import kotlinx.coroutines.experimental.async
import org.jetbrains.anko.coroutines.experimental.bg

class TeamsPresenter(private val view: TeamsView,
                     private val apiRepository: ApiRepository,
                     private val gson: Gson
) {
    fun getTeamList(league: String?) {
        view.showLoading()

        async(UI){
            val data = bg {
                gson.fromJson(apiRepository
                    .doRequest(TheSportDBApi.getTeams(league)),
                    TeamResponse::class.java
                )
            }
            view.showTeamList(data.await().teams)
            view.hideLoading()
        }
    }   
}

этот класс докладчика отлично работает на Kotlin 1.2.71, но я не могу заставить его работать на Kotlin 1.3.0.

Я обновил версию Kotlin в build.gradle проекта, удалил «экспериментальные сопрограммы» и добавил зависимость ядра сопрограммы kotlin:

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.0.0'

и это мой текущий код:

import com.google.gson.Gson

class TeamsPresenter(private val view: TeamsView,
                     private val apiRepository: ApiRepository,
                     private val gson: Gson
) {
    fun getTeamList(league: String?) {
        view.showLoading()

        async(UI){
            val data = bg {
                gson.fromJson(apiRepository
                    .doRequest(TheSportDBApi.getTeams(league)),
                    TeamResponse::class.java
                )
            }
            view.showTeamList(data.await().teams)
            view.hideLoading()
        }
    }
}

Ошибка в основном для асинхронных функций, пользовательского интерфейса и функции bg:

unresolved reference: async
unresolved reference: UI
unresolved reference: bg

Как мне заставить это работать на Kotlin 1.3.0? За любую помощь, заранее спасибо.

Ответы [ 3 ]

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

Ваш код имеет несколько уровней проблем:

  1. Вы используете async, но вы не await на нем. Вы должны использовать launch вместо.
  2. Вы используете средство pre-сопрограммы bg, эквивалентное async
  3. Вы немедленно await на bg, что означает, что вы должны использовать withContext(Default) вместо
  4. (новое с Kotlin 1.3) Вы не применяете структурированный параллелизм

Вот так должен выглядеть ваш код в Kotlin 1.3:

fun CoroutineScope.getTeamList(league: String?) {
    view.showLoading()
    this.launch {
        val data = withContext(Dispatchers.IO) {
            gson.fromJson(apiRepository.doRequest(TheSportDBApi.getTeams(league)),
                    TeamResponse::class.java
            )
        }
        view.showTeamList(data.teams)
        view.hideLoading()
    }
}

Вы должны вызывать свою функцию с областью сопрограмм, соответствующей вашей ситуации. Типичный подход привязывает это к вашей деятельности:

class MyActivity : AppCompatActivity(), CoroutineScope {
    lateinit var masterJob: Job
    override val coroutineContext: CoroutineContext
        get() = Dispatchers.Main + masterJob

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        masterJob = Job()
    }

    override fun onDestroy() {
        super.onDestroy()
        masterJob.cancel()
    }
}
0 голосов
/ 13 ноября 2018

Также добавьте

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

Вот исправление (я не знаю, является ли это лучшим способом сделать это):

import com.google.gson.Gson
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.launch

class TeamsPresenter(private val view: TeamsView,
                     private val apiRepository: ApiRepository,
                     private val gson: Gson
) {
    fun getTeamList(league: String?) {
        view.showLoading()
        CoroutineScope(Dispatchers.Main).launch {
            val data = async {
                gson.fromJson(apiRepository
                    .doRequest(TheSportDBApi.getTeams(league)),
                    TeamResponse::class.java
                )
            }
            view.showTeamList(data.await().teams)
            view.hideLoading()
        }
    }
}
0 голосов
/ 05 ноября 2018

вы должны использовать GlobalScope.launch вместо запуска, GlobalScope.async вместо async Dispatcher.main вместо пользовательского интерфейса

coroutineBasics

...