web-dev-qa-db-fra.com

Comment migrer Kotlin de 1.2 vers Kotlin 1.3.0 puis d'utiliser asynchrone, interface utilisateur et bg dans une fonction de présentateur

J'utilise le modèle MVP sur un projet Kotlin. J'ai un cours de présentateur:

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()
        }
    }   
}

cette classe de présentateurs fonctionne très bien sur Kotlin 1.2.71, mais je ne parviens pas à le faire fonctionner sur Kotlin 1.3.0. 

J'ai mis à jour la version de Kotlin dans le fichier build.gradle du projet, enlevé les "coroutines expérimentales" et ajouté la dépendance de base de kotlin coroutine:

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

et ceci est mon code actuel:

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()
        }
    }
}

Erreur principalement sur les fonctions asynchrone, d'interface utilisateur et bg: 

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

Comment puis-je obtenir que cela fonctionne sur Kotlin 1.3.0? pour toute aide, merci d'avance.

5
Dika

vous devez utiliser GlobalScope.launch au lieu de lancer, GlobalScope.async au lieu de async.

coroutineBasics

2
Kourosh

Ajoutez aussi

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

Voici une solution (je ne sais pas si c'est la meilleure façon de le faire): 

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()
        }
    }
}
1
Sid G

Votre code a plusieurs niveaux de problèmes:

  1. Vous utilisez async, mais vous ne await pas dessus. Vous devriez utiliser launch à la place.
  2. Vous utilisez le service de pré-évaluation de bg, équivalent à async
  3. Vous avez immédiatement await sur bg, ce qui signifie que vous devriez utiliser plutôt withContext(Default)
  4. (nouveau avec Kotlin 1.3) Vous ne postulez pas concurrence simultanée structurée

Voici à quoi devrait ressembler votre code dans 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()
    }
}

Vous devez appeler votre fonction avec la portée de coroutine appropriée à votre situation. Une approche typique est liée à votre activité:

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()
    }
}
1
Marko Topolnik