• 20 hours
  • Medium

Free online content available in this course.

Paperback available in this course

You can get support and mentoring from a private teacher via videoconference on this course.

Got it!

Last updated on 2/26/19

Votre première application

Log in or subscribe for free to enjoy all this course has to offer!

Ce chapitre est très important. Il vous permettra d'enfin mettre la main à la pâte, mais surtout on abordera la notion de cycle d'une activité, qui est la base d'un programme pour Android. Si pour vous un programme débute forcément par unmain, vous risquez d'être surpris !

On va tout d'abord voir ce qu'on appelle des activités et comment les manipuler. Sachant que la majorité de vos applications (si ce n'est toutes) contiendront plusieurs activités, il est indispensable que vous maîtrisiez ce concept ! Nous verrons aussi ce que sont les vues et nous créerons enfin notre premier projet — le premier d'une grande série — qui n'est pas, de manière assez surprenante, unHello World! . Enfin presque !

Activité et vue

Qu'est-ce qu'une activité ?

Si vous observez un peu l'architecture de la majorité des applications Android, vous remarquerez une construction toujours à peu près similaire. Prenons par exemple l'application du Play Store. Vous avez plusieurs fenêtres à l'intérieur même de cette application : si vous effectuez une recherche, une liste de résultats s'affichera dans une première fenêtre et si vous cliquez sur un résultat, une nouvelle fenêtre s'ouvre pour vous afficher la page de présentation de l'application sélectionnée. Au final, on remarque qu'une application est un assemblage de fenêtres entre lesquelles il est possible de naviguer.

Ces différentes fenêtres sont appelées desactivités. Un moyen efficace de différencier des activités est de comparer leur interface graphique : si elles sont radicalement différentes, c'est qu'il s'agit d'activités différentes. De plus, comme une activité remplit tout l'écran, votre application ne peut en afficher qu'une à la fois. La figure suivante illustre ce concept.

En cliquant sur un élément de la liste à gauche, on ouvre une nouvelle activité
En cliquant sur un élément de la liste à gauche, on ouvre une nouvelle activité

Faire une recherche ouvre une liste de resultats, comme dans l'écran de gauche. Toucher un résultat de la recherche ouvre un nouvel écran, dont l'interface graphique n'a rien à voir avec le précédent. Il s'agit donc de deux activités différentes.

Voici un autre exemple. Imaginez que vous naviguiez sur OpenClassrooms avec votre téléphone, le tout en écoutant de la musique sur ce même téléphone. Il se passe deux choses dans votre système :

  • La navigation sur internet, permise par une interface graphique (la barre d'adresse et le contenu de la page web, au moins) ;

  • La musique, qui est diffusée en fond sonore, mais qui n'affiche pas d'interface graphique à l'heure actuelle puisque l'utilisateur consulte le navigateur.

On a ainsi au moins deux applications lancées en même temps ; cependant, le navigateur affiche une activité alors que le lecteur audio n'en affiche pas.

Cependant, ce n'est pas le rôle de l'activité que de créer et de disposer les éléments graphiques, elle n'est que le conteneur qui va contenir, entre autre, les objets graphiques et elle va établir les liens entre l'interface graphique et la logique programmatique.

De plus, une activité contient des informations sur l'état actuel de l'application : ces informations s'appellent lecontext. Cecontextconstitue un lien avec le système Android ainsi que les autres activités de l'application, comme le montre la figure suivante.

Une activité est constituée du contexte de l'application et d'une seule et unique interface graphique
Une activité est constituée du contexte de l'application et d'une seule et unique interface graphique

États d'une activité

Si un utilisateur reçoit un appel, il devient plus important qu'il puisse y répondre que de faire en sorte qu'il puisse écouter la chanson que votre application diffuse. Pour pouvoir toujours répondre à ce besoin, les développeurs d'Android ont eu recours à un système particulier :

  • À tout moment votre application peut laisser place à une autre application, qui a une priorité plus élevée. Si votre application utilise trop de ressources système, alors elle empêchera le système de fonctionner correctement et Android l'arrêtera sans vergogne.

  • Votre activité existera dans plusieurs états au cours de sa vie, par exemple un état actif pendant lequel l'utilisateur l'exploite, et un état de pause quand l'utilisateur reçoit un appel.

Pour être plus précis, quand une application se lance, elle se met tout en haut de ce qu'on appelle la pile d'activités.

Fonctionnement de la pile d'activités
Fonctionnement de la pile d'activités

L'activité que voit l'utilisateur est celle qui se trouve au-dessus de la pile. Ainsi, lorsqu'un appel arrive, il se place au sommet de la pile et c'est lui qui s'affiche à la place de votre application, qui n'est plus qu'à la deuxième place. Votre activité ne reviendra qu'à partir du moment où toutes les activités qui se trouvent au-dessus d'elle seront arrêtées et sorties de la pile. On retrouve ainsi le principe expliqué précédemment, on ne peut avoir qu'une application visible en même temps sur le terminal, et ce qui est visible est l'interface graphique de l'activité qui se trouve au sommet de la pile.

Une activité peut se trouver dans trois états qui se différencient surtout par leur visibilité :

État

Visibilité

Description

Active
active» ou «running»)

L'activité est visible en totalité.

Elle est sur le dessus de la pile, c'est ce que l'utilisateur consulte en ce moment même et il peut l'utiliser dans son intégralité.
C'est cette application qui a le focus, c'est-à-dire que l'utilisateur agit directement sur l'application.

Suspendue
paused»)

L'activité est partiellement visible à l'écran.
C'est le cas quand vous recevez un SMS et qu'une fenêtre semi-transparente se pose devant votre activité pour afficher le contenu du message et vous permettre d'y répondre par exemple.

Ce n'est pas sur cette activité qu'agit l'utilisateur.
L'application n'a plus le focus, c'est l'application au-dessus qui l'a. Pour que notre application récupère le focus, l'utilisateur devra se débarrasser de l'application partiellement au-dessus pour que l'utilisateur puisse à nouveau interagir avec notre activité.
Si le système a besoin de mémoire, il peut très bien tuer l'application.

Arrêtée
stopped»)

L'activité est tout simplement invisible pour l'utilisateur, car une autre activité prend toute la place sur l'écran.

L'application n'a évidemment plus le focus, et puisque l'utilisateur ne peut pas la voir, il ne peut pas agir dessus.
Le système retient son état pour pouvoir reprendre, mais il peut arriver que le système tue votre application pour libérer de la mémoire système.

Mais j'ai pourtant déjà vu des systèmes Android avec deux applications visibles en même temps !

Ah oui, c'est possible. Mais il s'agit d'un artifice, il n'y a vraiment qu'une application qui est active. Pour faciliter votre compréhension, je vous conseille d'oublier ces systèmes.

Cycle de vie d'une activité

Une activité n'a pas de contrôle direct sur son propre état (et par conséquent vous non plus en tant que programmeur), il s'agit plutôt d'un cycle rythmé par les interactions avec le système et d'autres applications. Voici un schéma qui présente ce que l'on appelle le cycle de vie d'une activité, c'est-à-dire qu'il indique les étapes que va traverser notre activité pendant sa vie, de sa naissance à sa mort. Vous verrez que chaque étape du cycle est représentée par une méthode. Nous verrons comment utiliser ces méthodes en temps voulu.

Cycle de vie d'une activité
Cycle de vie d'une activité

Pour rappel, un package est un répertoire qui permet d'organiser notre code source, un récipient dans lequel nous allons mettre nos classes de façon à pouvoir trier votre code et différencier des classes qui auraient le même nom. Concrètement, supposez que vous ayez à créer deux classesX— qui auraient deux utilisations différentes, bien sûr. Vous vous rendez bien compte que vous seriez dans l'incapacité totale de différencier les deux classes si vous deviez instancier un objet de l'une des deux classesX, et Java vous houspillera en déclarant qu'il ne peut pas savoir à quelle classe vous faites référence. C'est exactement comme avoir deux fichiers avec le même nom et la même extension dans un même répertoire : c'est impossible car c'est incohérent.

Pour contrer ce type de désagrément, on organise les classes à l'aide d'une hiérarchie. Si je reprends mon exemple des deux classesX, je peux les placer dans deux packages différentsYetZpar exemple, de façon à ce que vous puissiez préciser dans quel package se trouve la classeXsollicitée. On utilisera la syntaxeY.Xpour la classeXqui se trouve dans le packageYetZ.Xpour la classeXqui se trouve dans le packageZ. Dans le cas un peu farfelu du code source d'un navigateur internet, on pourrait trouver les packagesWeb.Affichage.Image,Web.Affichage.VideoetWeb.Telechargement.

Les vues (que nos amis anglais appellent view), sont ces fameux composants qui viendront se greffer sur notre échafaudage, il s'agit de l'unité de base de l'interface graphique. Leur rôle est de fournir du contenu visuel avec lequel il est éventuellement possible d'interagir. À l'instar de l'interface graphique en Java, il est possible de disposer les vues à l'aide de conteneurs, nous verrons comment plus tard.

Un non-Hello world!

Vous trouverez les fichiers créés dans le panneau de gauche (voir figure suivante). Vous pouvez aussi rechercher la classe à laquelle vous souhaitez accéder avec le raccourcis CTRL + N.

Le navigateur de fichiers
Le navigateur de fichiers

On y trouve notre premier grand répertoiresrc/, celui qui contiendra tous les fichiers sources.java. Ouvrez le seul fichier qui s'y trouve, chez moiPremiereActivite.java(en double cliquant dessus). Vous devriez avoir un contenu plus ou moins similaire à celui-ci :

package com.openclassrooms.fr.premierprojet;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;


public class PremiereActivite extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_premiere_activite);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.premiere_activite, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

Ah ! On reconnaît certains termes que je viens tout juste d'expliquer ! Cependant, Android Studio a fait du zèle et a créé des choses que je n'expliquerai que plus tard, alors je vais faire quelque chose que je n'aime pas faire, mais je vais vous demander de modifier du code sans comprendre pourquoi. Supprimez les méthodesonCreateOptionsMenu etonOptionsItemSelected afin d'obtenir :

package com.openclassrooms.fr.premierprojet;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;


public class PremiereActivite extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_premiere_activite);
    }
}

Je vais prendre toutes les lignes une par une, histoire d'être certain de ne déstabiliser personne.

package com.openclassrooms.fr.premierprojet;

Là, on déclare que notre programme se situe dans le packagecom.openclassrooms.fr.premierprojet. Si on veut faire référence à notre application, il faudra faire référence à ce package.

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

On importe des classes qui se trouvent dans des packages différents : les classesActivity,Bundle, et MenuetMenuItemqui se trouvent dans le même package. Deux de ces packages sont inutiles car nous avons supprimé des fonctions dans le code, comme le montre l'image suivante.

Les imports inutiles sont en gris
Les imports inutiles sont en gris

Pour résoudre ce problème, on va utiliser le raccourci clavier le plus magique d'Android Studio : ALT + ENTREE. Ce raccourci permet d'effectuer des corrections d'erreurs rapidement, ainsi que d'autres actions rapides. Ici, on vous propose de Optimize Imports. Appuyez sur ENTREE pour valider votre sélection.

public class PremiereActivite extends Activity {
  //…
}

On déclare ici une nouvelle classe,PremiereActivity, et on la fait dériver deActivity, puisqu'il s'agit d'une activité.

@Override
protected void onCreate(Bundle savedInstanceState)
  //…
}

Le petit@Overridepermet d'indiquer que l'on va redéfinir une méthode qui existait auparavant dans la classe parente, ce qui est logique puisque vous saviez déjà qu'une activité avait une méthodevoid onCreate()et que notre classe hérite deActivity.

Cette méthode est la première qui est lancée au démarrage d'une application, mais elle est aussi appelée après qu'une application a été tuée par le système en manque de mémoire ! C'est à cela que sert le paramètre de typeBundle:

  • S'il s'agit du premier lancement de l'application ou d'un démarrage alors qu'elle avait été quittée normalement, il vautnull.

  • Mais s'il s'agit d'un retour à l'application après qu'elle a perdu le focus et redémarré, alors il se peut qu'il ne soit pasnullsi vous avez fait en sorte de sauvegarder des données dedans, mais nous verrons comment dans quelques chapitres, puisque ce n'est pas une chose indispensable à savoir pour débuter.

Dans cette méthode, vous devez définir ce qui doit être créé à chaque démarrage, en particulier l'interface graphique.

super.onCreate(savedInstanceState);

L'instructionsupersignifie qu'on fait appel à une méthode ou un attribut qui appartient à la superclasse de la méthode actuelle, autrement dit la classe juste au-dessus dans la hiérarchie de l'héritage — la classe parente, c'est-à-dire la classeActivity.

Ainsi,super.onCreatefait appel auonCreatede la classeActivity, mais pas auonCreatedeMainActivity. Il gère bien entendu le cas où leBundleestnull. Cette instruction est obligatoire.

L'instruction suivante :

setContentView(R.layout.activity_premiere_activite);

sera expliquée en partie dans quelques instants.

En attendant, vous pouvez remplacer le contenu du fichier par celui-ci :

//N'oubliez pas de déclarer le bon package dans lequel se trouve le fichier !

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class PremiereActivite extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        TextView text = new TextView(this);
        text.setText("Bonjour, vous me devez 1 000 000€.");
        setContentView(text);
    }
}

Nous avons créé un object que j'ai appelétext. Cet object est de typeTextView, j'imagine que le nom est déjà assez explicite. :D Il s'agit d'une vue (View)… qui représente un texte (Text). J'ai changé le texte qu'affichera cette vue avec la méthodevoid setText(String text).

La méthodevoid setContentView (View vue)permet d'indiquer l'interface graphique de notre activité. Si nous lui donnons unTextView, alors l'interface graphique affichera ceTextViewet rien d'autre.

Créer une machine virtuelle

C'est quoi une machine virtuelle ?

C'est très simple. Vous utilisez un ordinateur, un téléphone ou une tablette pour lire ce cours j'imagine. Une machine virtuelle est un logiciel qui va simuler une machine physique avec ses caractéristiques propres.  Par exemple j'utilise régulièrement des machines virtuelles Linux sur mon ordinateur Windows pour faire du développement sous ces environnements. Je vais donc vous apprendre comment créer une machine virtuelle qui simulera une machine qui exécute Android afin que vous puissiez exécuter vos applications directement sur votre ordinateur.

Avant d'exécuter notre application, nous avons besoin d'un environnement qui hébergera notre application. Si vous avez déjà un téléphone physique et que vous l'avez configuré comme présenté dans le chapitre précédent, vous pouvez sauter ce passage mais je vous conseille de quand même le lire car il pourrait vous être utile.

On va commencer par s'intéresser à un groupement de boutons dans la barre d'outils d'Android Studio :

Ce groupement-ci
Ce groupement-ci

Voici à quoi servent ces boutons :

  • Le premier bouton est compliqué à expliquer à l'heure actuelle. Il permet de synchroniser votre projet avec les scripts Gradle qui lui sont associés, mais nous verront tout ça plus tard car tout expliquer maintenant ne ferait que vous embrouiller.

  • Le second bouton permet de lancer l'AVD Manager, c'est-à-dire l'outil pour gérer les AVD(Android Virtual Device), en d'autres termes les machines virtuelles qui vont exécuter Android.

  • Le troisième bouton permet de lancer leSDK Manager, l'outil que nous avons vu dans le chapitre précédent et qui permettait de gérer les paquets que nous utilisons pour le développement de nos applications.

  • Enfin le dernier bouton ouvre l'Android Device Monitor, une interface graphique qui permet de manipuler facilement un ensemble d'outils d'analyse et de débogage.

Le bouton qui nous intéresse est le second, cliquez dessus :

Page d'accueil quand vous ne possédez pas encore d'AVD
Page d'accueil quand vous ne possédez pas encore d'AVD

Cliquez sur le bouton Create a new virtual device au milieu de l'écran :

Écran de sélection du matériel à émuler
Écran de sélection du matériel à émuler

Nous allons choisir ici le matériel que nous souhaitons émuler. Le menu de gaucheCategory vous permet de sélectionner si vous souhaitez émuler un téléviseur, un téléphone, un équipement mettable (wearable en anglais) ou une tablette. Ces catégories vous permettent de sélectionner un équipement précis dans la fenêtre centrale.

Ce ne sont que des exemples embarqués avec l'application, vous pouvez créer d'autres matériels en cliquant sur le bouton New Hardware Profileen bas à gauche.

Moi j'ai choisi de créer un équipement qui correspondra à unNexus 5, je le sélectionne donc dans le menu central et je clique surNext.

Nous pouvons sélectionner ici une version d'Android à installer sur notre AVD
Nous pouvons sélectionner ici une version d'Android à installer sur notre AVD

Sur cet écran, chaque ligne correspond à une version d'Android. La colonne de gauche est le nom commercial de la version et la seconde colonne son numéro d'API comme expliqué au chapitre précédent. La colonne suivante est très importante, elle représente l'ABI(Application binary interface), l'interface de communication entre le processus de l'AVD et la version d'Android. Si vous sélectionnezx86, ce sera comme si votre émulateur avait un processus x86sur 32 bits, si vous sélectionnezx86_64, idem mais sur 64 bits, enfin armabi-v7acorrespond à un processeur ARM. Comme votre processeur sera de type x86oux86_64, je vous conseille de sélectionner une de ces valeurs, parce que si vous sélectionnezarmabi-v7a, votre processeur devra se forcer à réfléchir comme un processeur ARM, ce qui est très compliqué pour lui, et l'émulation sera du coup très lente.

Enfin la dernière colonne représente la cible. Soit une version standard d'Android, soit une version d'Android sur laquelle sont installés les outils de Google (Google Maps par exemple).

Une fois la bonne version sélectionnée, cliquez surNext.

Les derniers paramètres pour notre SVD
Les derniers paramètres pour notre AVD

Enfin, nous allons pouvoir sélectionner les derniers paramètres pour notre AVD. En théorie tous les paramètres devraient suffire à votre bonheur, je vous invite donc à cliquer surFinish directement.

Notre machine virtuelle a été créée avec succès, nous allons maintenant faire en sorte que notre application s'exécute dessus.

Lancement de l'application

Pour lancer notre application, regardez la barre d'outils en haut d'Android Studio. Vous trouverez cet ensemble de boutons :

Les boutons pour compiler, exécuter ou déboguer votre application
Les boutons pour compiler, exécuter ou déboguer votre application
  • Le premier bouton vous sert à compiler votre application.

  • La liste déroulante à coté vous permet de sélectionner une configuration pour l'exécution pour le debogage. A chaque fois que vous lancez votre application (que ce soit en débug ou pour des tests), vous commencez toujours en fonction de la configuration sélectionnée ici. On parlera plus largement de ces configurations plus tard.

  • Le troisième bouton permet d'exécuter normalement l'application.

  • Le quatrième permet de déboguer l'application, avec des breakpoints (points d'arrêt en français, ne vous étonnez pas si j'utilise des termes anglophones par moment car ce sont les termes les plus utilisés dans le monde professionnel).

  • Enfin, le dernier permet de sélectionner un processus qui correspond à une machine virtuelle afin de déboguer dans ce processus-là. Utile si vous avez déjà un AVD lancé.

Pour l'instant on va juste exécuter notre application normalement, donc cliquez sur le troisième bouton, celui qui ressemble au symbole « play ».

Une fenêtre va s'ouvrir pour vous permettre de sélectionner le support sur lequel vous souhaitez exécuter l'application:

Sur quel support souhaitez-vous que l'application s'exécute ?
Sur quel support souhaitez-vous que l'application s'exécute ?

Si vous avez un téléphone configuré, dont les drivers sont installés sur votre ordinateur et qui est connecté à votre ordinateur, alors vous pourrez le sélectionner en choisissant l'optionChoose a running device, sinon, sélctionnez l'émulateur que nous avons créé auparavant avecLaunch emulator puis cliquez surOK.

Et voilà ! L'utilisateur vous doit 1 000 000 € !

La présentation peut être différente chez vous en fonction de votre version d'Android
La présentation peut être différente chez vous en fonction de votre version d'Android

Récapitulatif

  • Pour avoir des applications fluides et optimisées, il est essentiel de bien comprendre le cycle de vie des activités.

  • Chaque écran peut être considéré comme uneActivity, qui est constitué d'un contexte et d'une interface graphique. Le contexte fait le lien entre l'application et le système alors que l'interface graphique se doit d'afficher à l'écran des données et permettre à l'utilisateur d'interagir avec l'activité.

  • Pour concevoir une navigation impeccable entre vos différentes activités, vous devez comprendre comment fonctionne la pile des activités. Cette structure retirera en premier la dernière activité qui aura été ajoutée.

Example of certificate of achievement
Example of certificate of achievement