Codage d'applications Android fonctionnelles dans Kotlin Lambdas, Null Safety & More

Dans cette série en trois parties, nous avons examiné en détail Kotlin, un langage de programmation moderne pour les applications Android qui s'exécute dans la machine virtuelle Java (JVM).. 

Bien que Kotlin soit loin d'être le seul langage de programmation alternatif conçu pour fonctionner sur la machine virtuelle Java, il a beaucoup à offrir aux développeurs Android. Donc, si vous vous êtes récemment senti frustré par la partie Java du développement Android, vous voudrez peut-être envisager d'essayer Kotlin..

Dans les deux premiers versements, nous avons couvert les éléments suivants:

  • Java vs Kotlin: Devriez-vous utiliser Kotlin pour le développement Android? Dans cet article d'introduction, nous avons examiné ce que Kotlin pouvait offrir aux développeurs Android, ainsi que certains inconvénients potentiels que vous devez connaître avant de décider si Kotlin vous convient..

  • Codage d'applications Android fonctionnelles dans Kotlin: Mise en route. Dans cet article, nous avons examiné comment configurer Android Studio pour prendre en charge le code Kotlin, créé une application Android entièrement écrite en Kotlin, familiarisé avec la syntaxe de base de Kotlin et compris que le passage à Kotlin pouvait vous éviter de devoir écrire une autre findViewById encore.

Maintenant que vous êtes en mesure de remplacer les parties Java de vos projets par du code Kotlin ayant le même résultat final, passons à autre chose et examinons certaines zones dans lesquelles Kotlin dispose du avantage sur Java.

Dans cette dernière partie, nous allons explorer certaines des fonctionnalités les plus avancées de Kotlin qui vous permettent d’exécuter des tâches beaucoup plus détaillées en Java, ou impossibles à réaliser avec Java seul..

À la fin de cet article, vous saurez comment utiliser Kotlin pour supprimer une tonne de code passe-partout de vos projets, étendre les classes existantes avec de nouvelles fonctionnalités et rendre celles-ci frustrantes. NullPointerExceptions une chose du passé.  

Pas plus nul

Combien de fois avez-vous rencontré un NullPointerException tout en testant votre code? Aujourd’hui, il est assez clair que permettre aux développeurs d’attribuer la valeur null à une référence d’objet n’était pas la solution. meilleur choix de design! Tenter d'utiliser une référence d'objet ayant une valeur null est une énorme source de bogues dans de nombreux langages de programmation, y compris Java. En réalité, NullPointerException a été une telle source de contrariété que Java 8 a ajouté la @NonNull annotation spécifiquement pour essayer de corriger cette faille dans son système de types.

Le problème réside dans le fait que Java vous permet de définir n'importe quelle variable d'un type de référence sur null. Toutefois, si vous essayez à tout moment d'utiliser une référence pointant sur null, la variable ne saura pas où chercher, car l'objet n'existe pas réellement. À ce stade, la machine virtuelle Java ne peut pas continuer le chemin d’exécution normal. Votre application se bloquera et vous rencontrerez un problème. NullPointerException. Essayer d’appeler une méthode sur une référence null ou d’accéder à un champ d’une référence null déclenchera NullPointerException.

Si vous avez vécu la douleur de NullPointerExceptions (et n'avons-nous pas tout à un moment donné?) alors il y a une bonne nouvelle: la sécurité nulle est intégrée dans le langage Kotlin. Le compilateur Kotlin ne vous permet pas d'attribuer une valeur null à une référence d'objet, car il vérifie spécifiquement votre code pour la présence éventuelle d'objets null lors de la compilation. Si le compilateur Kotlin détecte qu'un NullPointerException peut être levé au moment de l'exécution, votre code échouera lors de la compilation.

La conception null-safe de Kotlin signifie que vous ne rencontrerez (presque) jamais de situations nulles et NullPointerExceptions provenant du code Kotlin. La seule exception est si vous déclenchez une NullPointerException en utilisant incorrectement l’un des opérateurs spéciaux de Kotlin, ou si vous utilisez un de ces opérateurs pour déclencher délibérément un NullPointerException (nous explorerons les opérateurs plus en détail plus tard dans cet article).

La sécurité nulle en pratique

Dans Kotlin, toutes les variables sont considérées par défaut comme non nullables. Par conséquent, toute tentative d'attribution d'une valeur null à une variable entraînera une erreur de compilation. Par exemple, les éléments suivants ne seront pas compilés:

var exemple: String = null

Si vous souhaitez qu'une variable accepte une valeur null, vous devez explicitement marquer cette variable comme nullable. C’est exactement le contraire de Java, où chaque objet est considéré comme pouvant être annulé par défaut, ce qui explique en grande partie pourquoi NullPointerExceptions sont si communs en Java.

Si vous souhaitez déclarer explicitement qu'une variable peut accepter une valeur null, vous devez ajouter une ? au type de variable. Par exemple, le suivant volonté compiler:

var exemple: String? = null

Lorsque le compilateur voit ce type de déclaration, il reconnaît qu'il s'agit d'une variable nullable et le traitera un peu différemment, notamment en vous empêchant d'appeler une méthode ou d'accéder à une propriété sur cette référence nullable, ce qui vous permet encore une fois d'éviter ces embêtants NullPointerExceptions. . Par exemple, les éléments suivants ne seront pas compilés:

var exemple: String? = null example.size

Bien que la conception de Kotlin signifie qu'il est difficile de rencontrer des exceptions NullPointerExceptions provenant du code Kotlin, si votre projet comporte un mélange de Kotlin et de Java, les parties Java de votre projet peuvent toujours être une source de NullPointerExceptions..

Si vous travaillez avec une combinaison de fichiers Kotlin et Java (ou si vous avez besoin d'introduire spécifiquement des valeurs NULL dans votre code Kotlin), Kotlin inclut une série d'opérations spéciales conçues pour vous aider à gérer avec élégance les valeurs NULL que vous rencontrez..

1. Le responsable de la sécurité des appels

L'opérateur Safe Call ?. vous offre un moyen de gérer les références susceptibles de contenir une valeur null, tout en garantissant que tout appel à cette référence n'entraînera pas NullPointerException.

Lorsque vous ajoutez un opérateur Safe Call à une référence, cette référence sera testée pour une valeur nulle. Si la valeur est null, alors null est renvoyé, sinon la référence de l'objet sera utilisée comme prévu. Bien que vous puissiez obtenir le même effet en utilisant un si déclaration, l’opérateur Safe Call vous permet d’effectuer le même travail dans beaucoup moins de code.

Par exemple, ce qui suit retournera une taille seulement si une n'est pas null sinon, il retournera null:

une taille

Vous pouvez également chaîner les opérateurs Safe Call ensemble:

nombre val = personne? .adresse?. rue ou .numéro

Si l'une des expressions de cette série est nulle, le résultat sera nul, sinon le résultat sera la valeur demandée.

2. L'opérateur Elvis

Parfois, vous aurez une expression qui pourrait potentiellement contenir une valeur null, mais vous ne voulez pas jeter un NullPointerException même si cette valeur Est-ce que se révéler nul.  

Dans ces situations, vous pouvez utiliser l'opérateur Elvis de Kotlin ?: pour fournir une valeur alternative qui sera utilisée chaque fois que la valeur s'avère nulle, ce qui est également un bon moyen d'empêcher la propagation de valeurs nulles dans votre code.

Regardons un exemple de l'opérateur Elvis en action:

 fun setName (name: String?) nom d'utilisateur = nom?: "N / A"

Ici, si la valeur à gauche de l’opérateur Elvis est ne pas null, la valeur du côté gauche est renvoyée (prénom). Mais si la valeur à gauche de l'opérateur Elvis est null, l'expression de droite sera renvoyée, ce qui est en l'espèce N / A.  

3. Le !! Opérateur

Si vous souhaitez forcer votre code Kotlin à générer une exception NullPointerException de style Java, vous pouvez utiliser le !! opérateur. Par exemple:

nombre val = prenom !!. longueur

Ici, nous utilisons le !! opérateur pour affirmer que le Prénom la variable n'est pas nulle. Aussi longtemps que Prénom contient une référence valide, le numéro de la variable est défini sur le longueur de la chaîne. Si Prénom ne contient pas de référence valide, alors Kotlin lancera un NullPointerException.

Expressions Lambda

Une expression lambda représente une fonction anonyme. Les Lambda sont un excellent moyen de réduire la quantité de code nécessaire pour effectuer certaines tâches qui apparaissent constamment dans le développement d'Android - par exemple, écrire des auditeurs et des rappels.. 

Java 8 a introduit les expressions lambda natives, qui sont désormais prises en charge par Android Nougat. Bien que cette fonctionnalité ne soit pas propre à Kotlin, il convient néanmoins de la regarder. De plus, si vous travaillez sur un projet contenant à la fois du code Kotlin et du code Java, vous pouvez désormais utiliser des expressions lambda dans l'ensemble de votre projet.!

Une expression lambda comprend un ensemble de paramètres, un opérateur lambda (->) et un corps de fonction, organisé dans le format suivant:

x: Int, y: Int -> x + y

Lors de la construction d'expressions lambda dans Kotlin, vous devez tenir compte des règles suivantes:

  • L'expression lambda doit être entourée d'accolades.

  • Si l'expression contient des paramètres, vous devez les déclarer avant la fin de -> symbole de la flèche.

  • Si vous travaillez avec plusieurs paramètres, séparez-les par des virgules..

  • Le corps va après le -> signe.

L'avantage principal des expressions lambda est qu'elles vous permettent de définir des fonctions anonymes, puis de les transmettre immédiatement en tant qu'expression. Cela vous permet d'effectuer de manière succincte de nombreuses tâches de développement courantes par rapport à Java 7 et aux versions antérieures, car vous n'avez plus besoin d'écrire la spécification de la fonction dans une classe ou une interface abstraite. En fait, le manque de Lambda dans Java 7 et les versions antérieures explique en grande partie pourquoi l'écriture pour les auditeurs et les rappels a toujours été si maladroite dans Android.  

Regardons un exemple courant: ajouter un écouteur de clic à un bouton. En Java 7 et versions antérieures, cela nécessiterait généralement le code suivant:

button.setOnClickListener (nouvelle View.OnClickListener () @Override public void onClick (View v) Toast.makeText (cela, "Bouton cliqué", Toast.LENGTH_LONG) .show (););

Cependant, les fonctions Kotlin lambda vous permettent de définir un écouteur de clic à l'aide d'une seule ligne de code:

button.setOnClickListener (view -> toast ("Bouton cliqué"))

Déjà, ceci est beaucoup plus succinct et facile à lire, mais nous pouvons aller plus loin: si une fonction prend une autre fonction comme dernier paramètre, vous pouvez le passer en dehors de la liste des parenthèses:

button.setOnClickListener () toast ("bouton cliqué")

Et si la fonction a seulement un paramètre qui est une fonction, vous pouvez supprimer complètement les parenthèses:

button.setOnClickListener toast ("Le bouton a été cliqué")

Fonctions d'extension

Semblable au C #, Kotlin vous permet d'ajouter de nouvelles fonctionnalités à des classes existantes que vous ne seriez pas en mesure de modifier. Donc, si vous pensez qu'une méthode utile manque à une classe, pourquoi ne pas l'ajouter vous-même, via une fonction d'extension?

Vous créez une fonction d'extension en préfixant le nom de la classe que vous souhaitez étendre au nom de la fonction que vous créez..

Par exemple:

fun AppCompatActivity.toast (msg: String) Toast.makeText (this, msg, Toast.LENGTH_LONG) .show ()

Notez que le ce mot-clé à l'intérieur de la fonction d'extension correspond à la AppCompatActivity exemple qui .pain grillé est appelé.

Dans cet exemple, il vous suffit d’importer le AppComptActivity et Pain grillé cours dans votre .kt déposer et vous êtes prêt à appeler le . notation sur les instances de la classe étendue.

En ce qui concerne le développement Android, vous pouvez trouver les fonctions d’extension particulièrement utiles pour ViewGroups la capacité de se gonfler, par exemple:

fun ViewGroup.inflate (@LayoutRes layoutRes: Int, attachToRoot: Boolean = false): Voir retourner LayoutInflater .from (context) .inflate (layoutRes, this, attachToRoot)

Donc, au lieu d'avoir à écrire ce qui suit:

val view = LayoutInflater .from (parent) .inflate (R.layout.activity_main, parent, false)

Vous pouvez simplement utiliser votre fonction d'extension:

val view = parent.inflate (R.layout.activity_main)

Objets Singleton

En Java, la création de singletons a généralement été assez détaillée, vous obligeant à créer une classe avec un constructeur privé, puis à créer cette instance en tant qu'attribut privé..

Le résultat final ressemble généralement à ceci:

public class Singleton privé statique Singleton singleton = new Singleton (); private Singleton ()  public statique Singleton getInstance () return singleton;  

Plutôt que de déclarer une classe, Kotlin vous permet de définir un seul objet, qui est sémantiquement identique à un singleton, dans une ligne de code:

objet KotlinSingleton 

Vous pouvez ensuite utiliser ce singleton tout de suite, par exemple:

objet KotlinSingleton fun myFunction () […] KotlinSingleton.myFunction ()

Conclusion

Dans cet article, nous avons examiné en détail la conception null-safe de Kotlin et avons vu comment vous pouvez vous assurer que vos projets Android restent nuls, même lorsqu'ils contiennent un mélange de code Java et Kotlin à l'aide d'opérateurs spéciaux. Nous avons également examiné comment utiliser les expressions lambda pour simplifier certaines tâches de développement courantes sous Android et comment ajouter de nouvelles fonctionnalités aux classes existantes..

En combinaison avec ce que nous avons appris dans la partie 1: Java contre Kotlin et la partie 2: prise en main, vous disposez désormais de tout ce dont vous avez besoin pour commencer à créer des applications Android efficaces à l'aide du langage de programmation Kotlin..

Amusez-vous avec le langage Kotlin et pourquoi ne pas consulter certains de nos autres cours et tutoriels sur la programmation Android?

  • Comprendre la concurrence sur Android avec HaMeR

    Dans ce didacticiel, nous allons explorer le cadre HaMeR (gestionnaire, message et exécutable), l'un des modèles de concurrence les plus puissants disponibles sur Android. Tu vas…
    Tin Megali
    SDK Android
  • Commencer avec Firebase pour Android

    La création d'un serveur principal nécessite des compétences qui font défaut à la plupart des développeurs d'applications indépendants. Heureusement, il existe Firebase, une plateforme basée sur le cloud qui…
    Ashraff Hathibelagal
    SDK Android
  • Android From Scratch: Capteurs matériels

    L'une des choses qui différencient le développement d'appareils mobiles des autres plates-formes est qu'un téléphone mobile ou une tablette est rempli de capteurs et…
    Paul Trebilcox-Ruiz
    SDK Android
  • Prenez des photos avec votre application Android

    Le Google Play Store propose des dizaines d'applications pour appareils photo, chacune permettant une manière différente de prendre des photos ou de faire quelque chose d'unique avec les photos du…
    Ashraff Hathibelagal
    SDK Android