SlideShare une entreprise Scribd logo
1  sur  88
Télécharger pour lire hors ligne
De Java à Kotlin
L'histoire d'une migration Android
@synapticrob
Bio
Android depuis 2009
OS
App
MOOC Udemy
Android / Kotlin
Python / Django
Go
@synapticrob
L'application
@synapticrob
L'application
Référentiel d'Abribus pour les techniciens
@synapticrob
L'application
Référentiel d'Abribus pour les techniciens
Identifié avec des Beacon
@synapticrob
@synapticrob
@synapticrob
@synapticrob
@synapticrob
Mon Objectif
Ajouter la lecture/écriture NFC
Ajouter les QRCode
Refondre le workflow de l'app
@synapticrob
Bonus
Migrer l'app en Kotlin
@synapticrob
Programme
1. Migrer de Java vers Kotlin
2. Les particularités de Kotlin
3. Et si c'était à refaire ?
@synapticrob
Migrer de Java vers Kotlin
@synapticrob
Java & Kotlin peuvent cohabiter
dans le même projet
@synapticrob
Comment procéder pour faire la
migration ?
@synapticrob
Par petits morceaux !
@synapticrob
Rule of Thumb
1 feature + 1 package migré
par itération
@synapticrob
Evite l'effet tunnel
pour les utilisateurs
@synapticrob
Permet de tester rapidement
le code migré
@synapticrob
Concrètement ?
@synapticrob
@synapticrob
Uniquement pour du code simple
@synapticrob
Les classes Model OK
@synapticrob
Les classes Model OK
// User.java
public class User {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
}
@synapticrob
Les classes Model OK
// User.kt
class User(var name: String?, var age: Int)
@synapticrob
Les fonctions OK
1. Extraire la fonction dans une classe Fake
2. Ajouter les dépendances manquantes petit à petit
3. Convertir le fichier en Kotlin
@synapticrob
Les classes complexes
Activity, Fragment, Service
NON
@synapticrob
Comment se passe
l'étape de compilation ?
@synapticrob
Compilation Java
@synapticrob
Compilation Kotlin
@synapticrob
L'introduction d'un seul fichier Kotlin
peut doubler le temps de compilation
@synapticrob
Compilation Kotlin
@synapticrob
Plus vous aurez de Kotlin
Plus le temps de compilation sera court
@synapticrob
Pour un projet avec plusieurs modules
Migrez par module
pour optimiser la compilation
@synapticrob
Sur Android on ne
pourra jamais éviter javac
@synapticrob
A cause de 2 fichiers
@synapticrob
A cause de 2 fichiers
R.java
BuildConfig.java
@synapticrob
Les particularités de Kotlin
@synapticrob
Les fonctions d'extensions
@synapticrob
Les fonctions d'extensions
.let { }
.apply { }
.run { }
.use { }
.also { }
with() { }
@synapticrob
Quand on découvre Kotlin...
@synapticrob
Quand on relit le code...
@synapticrob
companion object {
fun newInstance(arg: String): MyFragment {
return MyFragment().apply {
arguments = Bundle().apply {
putString(ARG, arg)
}
}
}
}
@synapticrob
companion object {
fun newInstance(arg: String): MyFragment {
val fragment = MyFragment()
fragment.arguments = Bundle().apply {
putString(ARG, arg)
}
return fragment
}
}
@synapticrob
Repérerez les 2 ou 3 extensions
que vous utilisez tout le temps
@synapticrob
Et limitez-vous à celles-ci !
@synapticrob
Mes préférés
.apply { }
.let { }
with() { }
@synapticrob
Fonctions d'extensions
et
Rétro-compatibilté
@synapticrob
Avoir ça qui traine dans le code...
if (android.os.Build.VERSION.SDK_INT >= 16) {
// ...
} else {
// ...
}
@synapticrob
On préfère éviter !
@synapticrob
Les fonctions d'extensions sont très
pratiques ici
@synapticrob
Centraliser la retro-compatibilité
// NfcCompat.kt
fun NdefRecord.toUriCompat(): Uri? {
return when {
android.os.Build.VERSION.SDK_INT >= 16 -> toUri()
else -> toUriOld()
}
}
@synapticrob
A l'usage
private fun parseNdefRecord(record: NdefRecord) : String {
return when (record.type) {
NdefRecord.RTD_URI -> record.toUriCompat().toString()
else -> record.payload.toString(NFC_CHARSET)
}
}
@synapticrob
Companion Object
@synapticrob
Où est passé mon static ?
@synapticrob
A quoi sert le static ?
@synapticrob
A quoi sert le static ?
Découpler une variable / fonction d'une
classe
@synapticrob
En Java, tout est classe !
@synapticrob
Puisque Kotlin permet de programmer
en dehors d'une classe...
@synapticrob
Le static n'est plus nécessaire
@synapticrob
Comment faire dans ce cas ?
public class StringUtils {
public static Date parseDate(String dateStr) {
// ...
}
}
@synapticrob
NOPE
class StringUtils {
companion object {
fun parseDate(dateStr: String) Date {
// ...
}
}
}
@synapticrob
Oui
object StringUtils {
fun parseDate(dateStr: String) Date {
// ...
}
}
@synapticrob
Utilisez les fonctions
Utilisez les object pour fournir un
namespace
@synapticrob
Et si c'était à refaire ?
@synapticrob
Encore plus d'extensions de fonctions custom
@synapticrob
Supprimer à 99% RxJava
@synapticrob
Supprimer à 99% RxJava
Remplacer par les Coroutines
@synapticrob
Promesse de Java
Write Once, Run Everywhere“ “
@synapticrob
Promesse de RxJava
Write Once, Debug Never“ “
@synapticrob
java.lang.IllegalStateException: Fatal Exception thrown on Scheduler.Worker thread.
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:62)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:442)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:150)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:264)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
Caused by: java.lang.StackOverflowError
okhttp3.HttpUrl.newBuilder (HttpUrl.java:633)
retrofit2.RequestBuilder.addQueryParam (RequestBuilder.java:144)
retrofit2.ParameterHandler$Query.apply (ParameterHandler.java:109)
retrofit2.ServiceMethod.toRequest (ServiceMethod.java:108)
retrofit2.OkHttpCall.createRawCall (OkHttpCall.java:178)
retrofit2.OkHttpCall.execute (OkHttpCall.java:162)
retrofit2.adapter.rxjava.RxJavaCallAdapterFactory$RequestArbiter.request
@synapticrob
Sur Android, pourquoi RxJava ?
@synapticrob
Dans la très large majorité des cas
Pour remplacer AsyncTask
@synapticrob
Syndrome de la bombe atomique
pour tuer une mouche
@synapticrob
Le seul endroit où j'ai vraiment
eu besoin de RxJava
@synapticrob
@synapticrob
Malgré tous mes efforts...
fun loadAll() {
disposables.add(Observable.zip(
dcpService.getBeaconMessagePositions(contract.id),
dcpService.getBeaconsByLocationName(location.name),
BiFunction { positions: List<Position>, beacons: List<Beacon> -> saveAndUpdateMessagePositions(positions, beacons) })
.applySchedulers()
.subscribe(
{ responseBeacons -> loadBeaconSuccess(responseBeacons) },
{ error -> loadBeaconFailure(error) }
)
)
}
@synapticrob
Pourquoi les Coroutines ?
@synapticrob
Plus facile à lire
GlobalScope.launch {
delay(1000)
println("Hello")
}
@synapticrob
Moins lourd à intégrer
suspend fun workload(n: Int): Int {
delay(1000)
return n
}
GlobalScope.async {
workload(n)
}
@synapticrob
Notion naturelle de scope
Très compatible avec Android
@synapticrob
ViewModelScope
class MyViewModel : ViewModel() {
fun loadData() {
viewModelScope.launch {
makeHttpRequest()
}
}
suspend fun makeHttpRequest() = withContext(Dispatchers.Default) {
// Async HTTP request
}
}
@synapticrob
Conclusion
@synapticrob
La migration s'est très bien passée
@synapticrob
Migrez par morceaux
(Et si c'est possible, ajoutez des tests au passage)
@synapticrob
Utilisez les fonctions d'extensions
(mais pas toutes, et pas tout le temps)
@synapticrob
Allez jeter un oeil aux Coroutines
(et gardez RxJava là où il est vraiment bon)
@synapticrob
Merci !
@synapticrob

Contenu connexe

Similaire à De Java à Kotlin - L'histoire d'une migration

Android Optimisations Greendroid
Android Optimisations GreendroidAndroid Optimisations Greendroid
Android Optimisations Greendroid
GDG Nantes
 
Grails from scratch to prod - MixIT 2011
Grails from scratch to prod - MixIT 2011Grails from scratch to prod - MixIT 2011
Grails from scratch to prod - MixIT 2011
Aurélien Maury
 
GPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge
GPars et PrettyTime - Paris JUG 2011 - Guillaume LaforgeGPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge
GPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge
Guillaume Laforge
 
Enib cours c.a.i. web - séance #5 : scala play! framework
Enib   cours c.a.i. web - séance #5 : scala play! frameworkEnib   cours c.a.i. web - séance #5 : scala play! framework
Enib cours c.a.i. web - séance #5 : scala play! framework
Horacio Gonzalez
 

Similaire à De Java à Kotlin - L'histoire d'une migration (20)

XebiCon'16 : Choisissez votre style avec Docker & Amazon Web Services Par Al...
XebiCon'16 : Choisissez votre style avec Docker & Amazon Web Services  Par Al...XebiCon'16 : Choisissez votre style avec Docker & Amazon Web Services  Par Al...
XebiCon'16 : Choisissez votre style avec Docker & Amazon Web Services Par Al...
 
Développer sereinement avec Node.js
Développer sereinement avec Node.jsDévelopper sereinement avec Node.js
Développer sereinement avec Node.js
 
Nouveautés Java 9-10-11
Nouveautés Java 9-10-11Nouveautés Java 9-10-11
Nouveautés Java 9-10-11
 
Android Optimisations Greendroid
Android Optimisations GreendroidAndroid Optimisations Greendroid
Android Optimisations Greendroid
 
XebiCon'16 : GraphQL et Falcor, un nouveau regard sur les architectures REST ...
XebiCon'16 : GraphQL et Falcor, un nouveau regard sur les architectures REST ...XebiCon'16 : GraphQL et Falcor, un nouveau regard sur les architectures REST ...
XebiCon'16 : GraphQL et Falcor, un nouveau regard sur les architectures REST ...
 
Ops@viadeo : Puppet & Co... 6 mois après par Xavier Krantz
Ops@viadeo : Puppet & Co... 6 mois après par Xavier KrantzOps@viadeo : Puppet & Co... 6 mois après par Xavier Krantz
Ops@viadeo : Puppet & Co... 6 mois après par Xavier Krantz
 
Paris Container Day 2016 : Choisissez votre style avec docker & Amazon Web Se...
Paris Container Day 2016 : Choisissez votre style avec docker & Amazon Web Se...Paris Container Day 2016 : Choisissez votre style avec docker & Amazon Web Se...
Paris Container Day 2016 : Choisissez votre style avec docker & Amazon Web Se...
 
Solutions Linux 2008 - JavaScript
Solutions Linux 2008 - JavaScriptSolutions Linux 2008 - JavaScript
Solutions Linux 2008 - JavaScript
 
Grails from scratch to prod - MixIT 2011
Grails from scratch to prod - MixIT 2011Grails from scratch to prod - MixIT 2011
Grails from scratch to prod - MixIT 2011
 
Realtime Web avec Akka, Kafka, Spark et Mesos - Devoxx Paris 2014
Realtime Web avec Akka, Kafka, Spark et Mesos - Devoxx Paris 2014Realtime Web avec Akka, Kafka, Spark et Mesos - Devoxx Paris 2014
Realtime Web avec Akka, Kafka, Spark et Mesos - Devoxx Paris 2014
 
Devoxx France 2023 - Les nouveautés de Java 19 et 20
Devoxx France 2023 - Les nouveautés de Java 19 et 20Devoxx France 2023 - Les nouveautés de Java 19 et 20
Devoxx France 2023 - Les nouveautés de Java 19 et 20
 
Gradle_NormandyJUG
Gradle_NormandyJUGGradle_NormandyJUG
Gradle_NormandyJUG
 
Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) f...
Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) f...Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) f...
Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) f...
 
GPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge
GPars et PrettyTime - Paris JUG 2011 - Guillaume LaforgeGPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge
GPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge
 
Cours JavaScript
Cours JavaScriptCours JavaScript
Cours JavaScript
 
Javascript Json artchitecture
Javascript  Json artchitecture Javascript  Json artchitecture
Javascript Json artchitecture
 
Enib cours c.a.i. web - séance #5 : scala play! framework
Enib   cours c.a.i. web - séance #5 : scala play! frameworkEnib   cours c.a.i. web - séance #5 : scala play! framework
Enib cours c.a.i. web - séance #5 : scala play! framework
 
Comprendre et maîtriser la performance de ses applications Spark
Comprendre et maîtriser la performance de ses applications SparkComprendre et maîtriser la performance de ses applications Spark
Comprendre et maîtriser la performance de ses applications Spark
 
Back to the future of java (from 8 to 11 and beyond)
Back to the future of java (from 8 to 11 and beyond)Back to the future of java (from 8 to 11 and beyond)
Back to the future of java (from 8 to 11 and beyond)
 
The future of JavaScript
The future of JavaScriptThe future of JavaScript
The future of JavaScript
 

De Java à Kotlin - L'histoire d'une migration