Par Valentin Brosseau / @c4software
Votre application vit seule, avec ses propres données.
Question : et si elles venaient d'un serveur ?
Le serveur met 10 secondes à répondre.
Que devient votre interface pendant ce temps ?
UIThread.IOThread.Sinon ? L'application plante 🚨
UIThread → l'interface, les clics
IOThread → le réseau, les traitements longsChacun son travail.
Ouvrir la connexion, envoyer la requête, décoder le JSON, changer de thread…
Vous écrivez tout ça à la main ?
<uses-permission android:name="android.permission.INTERNET" />Aucune confirmation n'est demandée à l'utilisateur.
[{ "id": 22, "name": "Valentin Brosseau", "content": "…", "done": true }]data class SampleObject(var id: Int, var name: String, var content: String, var done: Boolean)Un objet JSON = une data class.
interface ApiService {
@GET("/status")
suspend fun readStatus(@Query("identifier") identifier: String): Array<SampleObject>
@POST("/status")
suspend fun writeStatus(@Body status: SampleObject): Array<SampleObject>
}Vous décrivez l'API, Retrofit génère le code.
@GET, @POST, @PUT, @DELETE : le type d'appel et son lien.@Query : un paramètre dans l'URL.@Body : un objet envoyé en JSON.suspend, à votre avis ?
La fonction peut se mettre en pause, puis reprendre.
Elle attend la réponse du serveur, sans bloquer le thread.
OkHttp (timeout, logs, en-têtes)
+ GSON (conversion)
→ Retrofit → ApiServiceÉcrit une fois, dans un companion object.
CoroutineScope(Dispatchers.IO).launch {
runCatching {
val arrStatus = ApiService.instance.readStatus(identifier)
runOnUiThread {
dataSource.addAll(arrStatus)
}
}
}Dispatchers.IO : nous partons sur le thread réseau.readStatus(…) : l'appel, mis en pause jusqu'à la réponse.runOnUiThread : retour sur l'interface pour afficher.Et si vous oubliez le runOnUiThread ?
Vous manipulez la vue depuis le mauvais thread.
C'est la seconde règle d'Android 😉
ApiService dans un autre (remote.http par exemple).UIThread.data class par structure JSON.Dispatchers.IO pour l'appel.runOnUiThread pour mettre à jour la vue.Place au TP 🚀