Une première application¶
Dans ce chapitre, nous allons créer une premier projet avec Android Studio pour comprendre la structure d’une application Android.
Création d’une application simple¶
Lancez Android Studio et sur la fenêtre d’accueil, choisissez Start a new Android Studio project.

L’écran d’accueil d’Android Studio¶
Parmi la liste des modèles de projet, choisissez Empty Activity et cliquez sur le bouton Next.

L’écran de choix du modèle de projet¶
Puis vous devez préciser les informations relatives à votre projet : son nom, le package par défaut et la localisation du projet sur votre disque dur.
Le package correspond à l’identifiant technique de votre application. Si vous souhaitez déployer plus tard votre application sur Android Store, c’est le package qui permet d’identifier de manière unique votre application et l’organisation à qui elle appartient.

L’écran de configuration du projet¶
Important
Si vous utilisez Android Studio 3, n’oubliez pas de cocher la case Use AndroidX artifacts sur l’écran de configuration du projet !
AndroidX est une refonte d’une partie de l’API Android. Elle fournit une nouvelle implémentation de classes qui est compatible quelle que soit la version de l’API Android que vous utilisez dans votre projet. Il est recommandé d’utiliser AndroidX car l’ancienne API n’est actuellement plus maintenue.
Cliquez sur le bouton Finish et l’éditeur d’Android Studio s’ouvre une fois les fichiers du projet créés. Le projet est automatiquement construit et il ne doit pas y avoir d’erreur.

L’éditeur de projet Android Studio¶
Organisation du projet¶
Un projet Android Studio est géré par l’outil de build Gradle qui est un outil
dédié aux projets Java. Un projet géré par Gradle possède un ou plusieurs fichiers
build.gradle
pour configurer sa construction.
Les projets Android sont composés de modules. Les projets les plus simples n’ont
besoin que d’un seul module qui contient l’ensemble des fichiers sources. Par
défaut, un projet Android contient un seul module nommé app
. Dans le répertoire
de votre projet, vous pouvez trouver un répertoire app
qui contient
l’ensemble des fichiers pour ce module.

Structure des fichiers d’un projet Android¶
Dans le répertoire d’un module, vous trouverez un fichier build.gradle
pour configurer la construction du module et les répertoires suivants :
src/main/java
: ce répertoire contient les sources Java du modulesrc/main/res
: ce répertoire contient les ressources du module (Cf. plus bas)src/test/java
: ce répertoire contient les sources Java des tests unitairessrc/androidTest/java
: ce répertoire contient les sources Java des tests instrumentés (c’est-à-dire les tests qui doivent être exécutés directement sur un périphérique Android).libs
: ce répertoire contient éventuellement les bibliothèques nécessaires au modulebuild
: ce répertoire contient les fichiers de travail créés par Gradle.
On trouve également le fichier src/main/AndroidManifest.xml
qui correspond
au manifeste du module. Un fichier manifeste fournit au système l’ensemble des
informations nécessaires à l’exécution du module.
Par défaut, Android Studio affiche l’explorateur de fichiers à gauche de l’éditeur. Cet explorateur est par défaut en mode Android, c’est-à-dire qu’il vous affiche une vue adaptée. Il ne vous affiche donc pas l’organisation réelle des fichiers sur votre disque dur. Vous pouvez choisir le mode Project pour voir l’organisation réelle mais le mode Android est généralement plus lisible et plus adapté pour réaliser les développements.

La structure des fichiers présentée par Android Studio¶
Dans ce mode, vous avez le nom du module à la racine et vous trouvez directement les répertoires :
manifests
: qui contient le manifeste du modulejava
: qui présente toutes les sources Java en séparant les packages de l’application, des packages de tests (unitaires et instrumentés).res
: qui présente les répertoires de ressources (Cf. plus bas).Gradle Scripts
: ce répertoire regroupe tous les fichiers Gradle de l’application et des modules.
Lancement de l’application¶
Depuis Android Studio, vous pouvez lancer une application sur votre téléphone Android. Il vous suffit de brancher votre appareil en USB sur votre station de travail et de choisir le menu Run > Run “app”. Android Studio utilise l’outils adb (Android Debug Bridge) pour installer l’application créée sur votre appareil et l’exécuter. Une fois installée, l’application est accessible depuis le menu des applications Android sur votre appareil.
Pour pouvoir utiliser le mode debug depuis Android Studio, vous devez activer le mode developer sur votre appareil. Pour plus d’information, consultez le guide utilisateur :
Note
L’application générée par Gradle porte l’extension .apk
et se trouve
dans le répertoire app/build/output/debug
(pour le cas où le module
principal de l’application porte le nom par défaut app
).
L’émulateur Android¶
Si vous ne disposez pas d’un appareil Android ou si vous souhaitez tester votre application dans des conditions particulières, vous pouvez utiliser l’émulateur Android. Il vous permet de choisir le type d’appareil que vous souhaitez émuler.
Pour créer un émulateur, cliquez sur le menu Tools > AVD Manager (AVD pour Android Virtual Device).

Cliquez sur le bouton Create Virtual Device… pour ajouter, depuis la liste fournie, le modèle d’appareil à émuler.
À partir de la fenêtre du AVD Manager, vous pouvez directement lancer l’émulateur. Lorsque vous lancez votre application depuis Android Studio, l’émulateur apparaît dans la liste des périphériques disponibles.
Note
Si l’émulateur n’est pas lancé lorsque vous démarrez votre application, il sera préalablement lancé par Android Studio. L’émulateur peut consommer beaucoup de ressources systèmes, notamment au lancement. Je vous conseille de ne pas fermer l’émulateur après chaque test. Contentez-vous de relancer votre application depuis Android Studio de manière à ce qu’elle soit redéployée dans l’émulateur en cours d’exécution.
Notion d’activité¶
Le modèle de projet choisi génère le code pour une application avec une activité. Une activité est un composant d’une application Android qui représente un écran avec lequel l’utilisateur va pouvoir interagir. Un composant Android est représenté par une classe Java. Cependant, un composant n’est pas instancié directement dans le code de l’application. C’est lors de l’exécution que le système prend en charge la création et le cycle de vie d’un objet de cette classe. Dans le cas d’une activité, un objet correspondant est instancié par le système quand il est nécessaire d’afficher l’écran à l’utilisateur (par exemple au lancement de l’application).
Pour notre application, le générateur de projet a créé une classe MainActivity
dans le répertoire java
dont voici le code :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | package dev.gayerie.premiereapplication;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
|
La classe MainActivity
hérite de AppCompatActivity. Cette dernière fournit
du code de base pour la gestion d’une activité. Dans notre exemple, nous surchargeons
la méthode onCreate
pour changer le comportement de l’activité au moment de
sa création.
Important
Remarquez qu’à la ligne 11, la méthode onCreate
commence par appeler
sa super-implémentation. Cette manière de faire est courante dans l’API Android.
Lorsque l’on veut modifier le comportement de l’activité, il faut s’assurer
que le code d’origine est bien appelé pour que l’activité puisse fonctionner
correctement.
La ligne 12 constitue le seul véritable changement de comportement pour notre activité :
setContentView(R.layout.activity_main);
Une activité est associée à une vue, c’est-à-dire à une ensemble de composants graphiques prenant en charge le rendu de l’écran. Il est tout à fait possible de créer les composants de vue en Java mais il est plus facile d’utiliser un layout qui permettra de créer dynamiquement pour nous les composants nécessaires. La méthode setContentView attend en paramètre un identifiant de ressources d’un layout.
Nous allons voir dans la section suivante que la variable R.layout.activity_main
correspond en fait à l’identifiant d’une ressource qui décrit le rendu de l’activité.
Cette ligne de code permet donc de créer l’ensemble des composants graphiques
qui doivent s’afficher dans l’activité.
Notion de ressources¶
En plus du code Java, une application Android peut contenir un ensemble d’informations que l’on désigne de manière générale comme des ressources. Le type d’une ressource peut être très divers. Il peut s’agir d’un nombre, d’une chaîne de caractères, d’une image, d’un fichier quelconque, de la description du rendu d’une activité…
Les ressources sont stockés dans des sous-répertoires dans [module]/src/main/res
.
Dans le module par défaut app
, les ressources sont donc stockées dans app/src/main/res
.
Dans la vue Android de l’éditeur, le répertoire res
est directement affiché
sous le module. Par défaut, ce répertoire contient les sous-répertoires :
drawable
: ce répertoire contient les images (PNG, JPEG…) ou des fichiers XML décrivant des images vectorielles (format SVG).layout
: ce répertoire contient les fichiers XML décrivant la disposition des vues d’une activité.mipmap
: ce répertoire contient les icônes des l’application. Comme une application Android doit pouvoir être installée sur différents périphériques, il est nécessaire de fournir plusieurs résolutions de la même icône. La technique du mipmap consiste précisément à fournir plusieurs résolution d’une même image afin d’éviter la pixellisation à l’affichage en permettant au système de choisir la résolution adéquate.values
: ce répertoire contient les variables que l’on ne souhaite pas écrire en dur dans le code (comme les libellés et les messages).
Note
Il existe d’autres types de ressources. Par exemple, il est possible d’ajouter
un fichier quelconque dans le répertoire [module]/src/main/res/raw
.
Ce fichier peut ensuite être lu lors de l’exécution de l’application. Pour
en savoir plus :
Pour notre application, le répertoire app/res/layout
contient le fichier
activity_main.xml
. Il s’agit d’une fichier de layout, c’est-à-dire un
fichier qui décrit le rendu visuel de l’activité. Android Studio intègre un éditeur
de layout qui vous permet d’éditer graphiquement votre layout. L’éditeur est
ouvert par défaut lorsque vous double-cliquez sur le nom du fichier. Vous pouvez
à tout moment consulter le source XML en cliquant sur l’onglet Text
sous l’éditeur.

L’éditeur de layout¶
Accéder à un identifiant de ressource depuis le code Java¶
Toutes les ressources sont accessibles à partir de leur identifiant (une constante
numérique créée automatiquement par le compilateur). Depuis votre code Java,
l’identifiant est fourni par la classe R
. La classe R
est une classe dont
le code source est automatiquement écrit par Android Studio et qui est déclarée
dans le package par défaut de votre application. Pour accéder à l’identifiant
d’un layout, il faut écrire
R.layout.[nom du layout]
Le nom du layout correspond au nom du fichier XML en omettant l’extension.
De la même manière, vous pouvez accéder aux identifiants des fichiers dans
les différents sous-répertoires de ressources. Il existe une particularité
pour le répertoires values
. Ce dernier contient des fichiers XML
qui permettent de déclarer des valeurs comme des entiers, des valeurs booléennes,
des chaînes de caractères, des couleurs…
Si vous éditez le fichier app/res/values/strings.xml
, vous trouverez :
<resources>
<string name="app_name">Première Application</string>
</resources>
Ce fichier déclare une chaîne de caractères nommée app_name
est qui correspond
au nom de l’application. Pour accéder à l’identifiant de cette constante depuis
le code source Java, on utilise la classe R
de la manière suivante :
int appNameId = R.string.app_name;
Note
Il existe plusieurs classes R
dans l’API qui permettent d’accéder
aux identifiants de ressources fournies en standard par Android.
Accéder à une ressource depuis une autre ressource¶
Il est très souvent utile de pouvoir accéder à une ressource depuis une autre
ressource. C’est notamment le cas dans les fichiers de layout. Si l’on souhaite
placer un composant graphique avec un libellé, la valeur du libellé peut être
externalisé dans le fichier app/res/values/strings.xml
et avoir lui-même
un ID. Dans ce cas, on utilise la notation suivante :
@[type]/id
Par exemple, pour accéder au nom de l’application déclaré dans le fichier
app/res/values/strings.xml
, on écrira :
@string/app_name
On peut donc très facilement ajouter du texte dans le layout d’une activité pour afficher le nom de l’application:
<TextView
android:text="@string/app_name"
/>
N’importe quelle valeur peut être remplacée par un identifiant de ressource à condition que le type de la ressource soit compatible avec le type de la valeur.
Identifier une ressource dans un layout¶
Lorsqu’on définit un layout dans un fichier XML, il est utile de pouvoir associer un composant graphique à un identifiant. Nous verrons que nous pouvons alors récupérer en Java une référence sur ce composant à partir de son identifiant.
La déclaration d’un identifiant dans un layout XML se fait avec l’attribut
android:id
et le format de l’identifiant est :
@+id/[ID]
Par exemple, pour identifier un TextView dans un fichier XML de layout :
<TextView
android:id="@+id/monTexte"
/>
Exercices¶
Utiliser un identifiant de ressource dans le layout
Modifier le layout app/res/layout/activity_main.xml
afin que le
texte affiché dans l’activité soit externalisé dans le fichier
app/res/values/strings.xml
.
Ajouter un bouton
Modifiez le layout app/res/layout/activity_main.xml
afin d’ajouter
un bouton avec l’ID bouton
. Ajouter également l’ID texte
au libellé
(de type TextView) déjà présent dans le layout de l’activité.
Nous pouvons maintenant modifier le code Java de notre activité. La méthode
onCreate
est habituellement utilisée pour récupérer une référence sur les
Views (les composants graphiques) grâce à la méthode findViewById.
Avec une référence sur une View, on peut positionner des valeurs (par exemple
le contenu dans champ ou le texte à afficher) ou on peut ajouter des listeners
à appeler en réponse à une action utilisateur. Pour notre application,
nous allons enregistrer un listener pour agir lorsque l’utilisateur clique
sur le bouton.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | package dev.gayerie.premiereapplication;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private TextView texte;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
texte = findViewById(R.id.texte);
Button bouton = findViewById(R.id.bouton);
bouton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
texte.setText("Vous avez cliqué sur le bouton !");
}
});
}
}
|
Aux lignes 19 et 20, notez l’appel à la méthode findViewById qui attend
une identifiant de View et qui retourne l’objet correspondant au
composant graphique. Pour accéder à un identifiant, on utilise la classe
R
de la façon suivante :
R.id.[nom ID]
Améliorez le code de l’application en externalisation la chaîne de caractères
présente dans le code dans le fichier de ressources res/values/strings.xml
.
Note
Pour améliorer la lisibilité du code, vous pouvez utiliser les lambdas. Pour l’exercice précédent, vous pouvez écrire à la place :
package dev.gayerie.premiereapplication;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView texte = findViewById(R.id.texte);
Button bouton = findViewById(R.id.bouton);
bouton.setOnClickListener(v -> texte.setText("Vous avez cliqué sur le bouton !"));
}
}
Pour que votre projet compile, vous devez néanmoins activer le support Java 1.8.
Pour cela, éditez le fichier build.gradle
du module app
et
assurez-vous que la section suivante est bien présente dans la section android
:
android {
// ....
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
Vous devez ensuite resynchroniser votre projet comme demandé par Android Studio.
Le fichier AndroidManifest.xml¶
Chaque module de votre projet fournit un fichier manifeste nommé
AndroidManifest.xml
. Il se trouve dans le répertoire src/main
de
votre module. Android Studio l’affiche dans le répertoire manifests
.
Ce fichier est lu au lancement de l’application par
le système pour identifier le comportement de votre application. Nous verrons
au cours des chapitres suivants que ce fichier contient la déclaration de tous
les composants de votre application (activités, broadcast receivers, services)
mais aussi la déclaration des autorisations à demander à l’utilisateur à l’installation,
la version d’Android requise…
Pour notre application simple, le fichier AndroidManifest.xml
contient :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="dev.gayerie.premiereapplication">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
|
Parmi les nombreuses informations fournies, on peut regarder plus précisément :
ligne 3 : l’attribut
package
fournit le package identifiant l’application. C’est notamment dans ce package que la classeR
sera créée.ligne 5 : l’élément
application
marque le début de la déclaration des informations sur notre application.ligne 7 : l’attribut
android:icon
déclare l’icône de l’application qui pointe vers la ressource@mipmap/ic_launcher
.ligne 8 : l’attribut
android:label
fournit le nom de l’application à partir de la ressource@string/app_name
(déclarée dansapp/res/values/strings.xml
)ligne 12 : l’élément
activity
permet de déclarer une activité en fournissant sa classe d’implémentation grâce à l’attributandroid:name
. Remarquez que dans l’exemple, la classe d’implémentation de l’activité est.MainActivity
. Le point au début signale que la classe doit être cherchée dans le package de l’application. Donc l’activité est fournie par la classe :dev.gayerie.premiereapplication.MainActivity
les lignes 13 à 15 indiquent que cette activité est l’activité principale. Autrement dit, lorsque l’application est lancée par l’utilisateur, c’est cette activité qui doit être affichée. Nous reviendrons plus tard sur les notions d’intent et de filtre d’intent qui sont très importantes dans le développement Android pour l’échange d’information entre composants.