Android : les fondamentaux
Les composantes principales
Ce chapitre vous présente brièvement les grandes composantes d’une application Android.
1. Activité
Une activité représente un écran d’une application. Une application contient autant d’activités qu’il y a d’écrans. Une activité est en général composée de deux éléments : une classe Kotlin qui représente l’activité et un fichier XML qui permet de définir l’IHM de cette activité. Dans un modèle MVC, la classe Kotlin représente la partie contrôleur et le fichier XML représente la partie vue.
2. Intention
Une intention permet de demander au système d’exploitation Android d’exécuter une tâche spécifique. Cette tâche peut être l’exécution d’une nouvelle activité par exemple.
3. Fragment
Un fragment définit un écran ou un fragment d’écran dans le but de s’adapter aux différentes tailles d’appareils mobiles. Les fragments sont utilisés par les activités.
4. Service
Un service contient le traitement d’un service qui s’exécute en tâche de fond. Cela signifie qu’un service n’a pas d’interface graphique. Le traitement du service s’exécute sur le thread UI.
5. Content provider...
Activité
1. Présentation
Une activité représente un écran d’une application. Une application contient autant d’activités qu’il y a d’écrans.
Une seule activité peut être exécutée à la fois.
Une activité a un cycle de vie bien particulier. Plusieurs fonctions nommées "callback " s’exécutent automatiquement à des moments bien spécifiques du cycle de vie.
2. Pile de gestion
Lorsqu’une activité est créée, elle est empilée dans une pile de gestion appelée le stack. Cette pile de gestion fonctionne en mode LIFO (Last In First Out). Ainsi, une activité est empilée lorsqu’elle démarre et dépilée (détruite) lorsque l’on clique sur le bouton back du téléphone ou bien lorsque la fonction finish est appelée.
3. Création d’une activité
Pour créer une nouvelle activité :
Clic droit sur le package dans lequel il y aura la nouvelle activité.
Clic sur New.
Clic sur Activity.
Clic sur le type d’activité voulu. Dans l’exemple ci-dessous, une activité vide est ajoutée. C’est-à-dire Empty activity.
4. Contrôleur
La classe Kotlin héritant de la classe Activity est généralement utilisée comme contrôleur. C’est dans cette classe que l’on va redéfinir les callbacks et définir les fonctions à exécuter selon l’interaction avec l’utilisateur.
5. Cycle de vie
Les différents états
Une activité a quatre états possibles :
État |
Description |
En cours d’exécution |
L’activité est visible, en cours d’exécution et a le focus. |
En pause |
L’activité est visible et en cours d’exécution, mais n’a pas le focus.... |
Vue liée à l’activité
1. Présentation
On peut définir la vue d’une activité de deux façons différentes :
-
statiquement dans un fichier XML,
-
dynamiquement via la classe de l’activité.
Dans ce chapitre, seule la façon statique est présentée.
2. Fonctionnement de l’interface utilisateur
Tous les éléments de l’interface utilisateur d’une application Android sont construits à l’aide d’objets de types View et ViewGroup.
Un objet de type View est un objet qui dessine quelque chose sur l’écran avec lequel l’utilisateur peut interagir.
Un objet de type ViewGroup est un objet qui contient d’autres objets View afin de définir la disposition de l’interface.
Android fournit tout un panel de View et ViewGroup qui offrent la possibilité de créer des interfaces graphiques riches.
L’interface utilisateur de chaque composant de votre application est définie à l’aide d’une hiérarchie d’objets View et ViewGroup.
Chaque objet de type ViewGroup est un conteneur invisible qui organise des objets enfants de types View et ViewGroup.
3. Les conteneurs de type ViewGroup
a. Présentation
Il est nécessaire d’utiliser des ViewGroup pour positionner des composants dans votre interface graphique. Ces ViewGroup sont appelés "Layout" :
Voici les quatre principaux :
Layout |
Description |
GridLayout |
Permet une mise en page qui place les composants dans une grille rectangulaire. |
LinearLayout |
Permet une mise en page qui organise les composants en une seule ligne verticale ou horizontale. Il crée un scroll bar si la longueur de la fenêtre dépasse la longueur de l’écran. |
RelativeLayout |
Permet de spécifier l’emplacement des composants les uns par rapport aux autres. |
ConstraintLayout |
Permet de spécifier l’emplacement des composants les uns par rapport aux autres avec des fonctionnalités plus avancées que celles du RelativeLayout. |
Les exemples sont réalisés à chaque fois dans un nouveau projet dont l’activité principale se nomme MainActivity.
b. GridLayout
Attributs
Voici les principaux attributs d’un GridLayout :
Attribut |
Description |
android:columnCount |
Permet de définir le nombre de colonnes.... |
Gestion des événements
Il y a deux façons de lier un événement à un composant : soit via le XML, soit via Kotlin.
1. Gestion des événements via XML
Pour lier un composant à une fonction Kotlin, il faut définir l’attribut du composant représentant l’événement en lui donnant comme valeur le nom de la fonction Kotlin. La fonction Kotlin doit obligatoirement attendre en paramètre un objet de type View.
L’assistant d’Android studio permet de faciliter la création de la fonction Kotlin grâce au raccourci [Alt][Entrée].
Les exemples sont réalisés à chaque fois dans un nouveau projet dont l’activité principale se nomme MainActivity.
Activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- Utilisation d'un RelativeLayout permettant de spécifier l'emplacement
des composants les uns par rapport aux autres. -->
<!-- android:layout_width="match_parent" : Le layout sera aussi haut que
l'écran-->
<!-- android:layout_height="match_parent" : Le layout sera aussi large que
l'écran-->
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="fr.acos.myapp.MainActivity">
<!-- Button : Permet d'afficher un bouton simple-->
<!-- android:id="@+id/btn_valider" : btn_valider est l'identifiant du
composant -->
<!-- android:layout_width="match_parent" : Le composant sera aussi
large que son layout-->
<!-- android:layout_height="wrap_content" : Le composant sera aussi
haut que son contenu-->
<!--...
Gestion des ressources
1. Présentation
Les composants visuels d’une IHM, les fichiers XML, fichiers image, fichiers audio, fichiers vidéo, etc. sont vus comme des ressources. Chaque ressource a un identifiant. Il y a deux manières d’accéder à ces identifiants, la manière d’y accéder dépend de l’endroit où l’on se trouve : soit via un fichier Kotlin , soit via un fichier XML. La manière dont est défini un identifiant dépend du type de ressource : soit la ressource est contenue à l’intérieur d’un fichier XML, alors c’est au développeur de définir l’identifiant ; soit c’est un fichier, alors c’est le nom du fichier qui permet de définir l’identifiant.
a. Stocker les ressources
Dossier |
Ressources contenues dans le dossier |
res/anim |
Dossier pour les fichiers XML définissant des animations. |
res/color |
Dossier pour les fichiers XML contenant des ColorStateList. Une ColorStateList permet d’associer des états à des couleurs. Ensuite, on associe le fichier à une View par exemple. |
res/drawable |
Dossier pour n’importe quel type de fichier pouvant être affiché dans une vue :
|
res/mipmap |
Dossier pour les icônes. |
res/layout |
Dossier pour les fichiers XML définissant une interface utilisateur. |
res/menu |
Dossier pour les fichiers XML définissant un menu. |
res/raw |
Dossier pour les divers fichiers bruts. |
res/values |
Dossier pour les fichiers XML contenant des valeurs simples, telles que des chaînes, des entiers et des couleurs :
|
Manifeste
1. Présentation
Le manifeste est utilisé par les outils de compilation, par le système d’exploitation et par Google Play.
Une application contient obligatoirement un et seulement un manifeste. Un manifeste est un fichier XML. Un manifeste contient la liste des activités, services, content provider et broadcastReceiver contenus dans l’application. Un manifeste contient aussi la liste des permissions nécessaires au bon fonctionnement de l’application et les permissions nécessaires aux autres applications désireuses d’accéder aux informations de l’application.
Chaque composant présent dans le manifeste contient des attributs permettant de définir des informations de base telles que la classe représentant le composant, son intitulé…
Les intent filter sont définis dans le manifeste.
2. Les balises
Liste des principales balises utilisées dans un manifeste :
<action> |
Ajoute une action à un filtre d’intention. |
<activity> |
Déclare un composant d’activité. |
<activity-alias> |
Déclare un alias pour une activité. |
<application> |
Déclaration de l’application. |
<category> |
Ajoute un nom de catégorie à un filtre d’intention. |
<compatible-screens> |
Spécifie chaque configuration d’écran avec laquelle l’application est compatible. |
<data> |
Ajoute un type de données à un filtre d’intention. |
<intent-filter> |
Spécifie les types d’intentions auxquels une activité, un service... |
Gestion des droits
1. Présentation
Pour maintenir la sécurité du système et des utilisateurs, Android exige que les applications demandent l’autorisation avant d’utiliser certaines données et fonctionnalités du système. En fonction de la sensibilité de la zone, le système peut accorder l’autorisation automatiquement ou demander à l’utilisateur d’approuver la demande.
Les permissions sensibles sont celles permettant l’écriture et la lecture du calendrier, l’utilisation de la caméra, la gestion des contacts, la localisation, l’utilisation du micro, la gestion des appels téléphoniques, la gestion des SMS et la lecture et l’écriture de données sur les cartes mémoire du téléphone.
2. Fonctionnement
Les permissions nécessaires à une application doivent être obligatoirement définies dans le fichier AndroidManifest.xml grâce à la balise uses-permission. Il y a autant de balises uses-permission que de permissions.
Pour les permissions sensibles, il faut ajouter dans le code les instructions demandant une autorisation directe à l’utilisateur. Une fois que la permission est donnée par l’utilisateur, un callback nommé onRequestPermissionsResult est appelé automatiquement.
3. Syntaxe
Voici la syntaxe de la balise permettant de définir une permission dans le manifeste :
<uses-permission android:name="<permission>" />
Voici la syntaxe de la fonction permettant de faire une demande d’autorisation à l’utilisateur :...
Les intentions
1. Présentation
Une intention permet de demander au système d’exploitation Android d’exécuter une tâche spécifique. Il existe deux types d’intentions :
-
L’intention explicite : cette intention permet d’indiquer précisément quel composant sera exécuté : Activité, Service…
-
L’intention implicite : cette intention permet d’indiquer précisément quelle action doit être effectuée et alors le système d’exploitation trouve le composant adéquat.
La classe Intent permet de créer la demande. Cette demande doit être ensuite passée en paramètre à une fonction. Voici la liste des principales fonctions permettant d’exploiter un objet de type Intent :
Fonction |
Description |
startActivity() |
Permet de démarrer une activité. |
startService() |
Permet de démarrer un service. |
sendBroadcast() |
Permet d’exécuter un broadcastReceiver. |
2. Intent explicite
a. Présentation
L’intent explicite est souvent utilisé pour démarrer une nouvelle activité. Les intents explicites seront donc présentés avec cette utilisation.
b. Syntaxe
Voici la syntaxe permettant de créer un intent explicite :
val demande = Intent(<context>, <ActiviteCible>)
Paramètres |
|
context |
Objet représentant l’activité depuis laquelle l’intent sera exécuté. Pour rappel, la classe Activity hérite de la classe Context. |
activiteCible |
Le nom de la classe à exécuter. |
c. Exemple
Cet exemple permet de lancer une activité BActivity.
Exemple d’intent explicite
val intention = Intent(this, BActivity::class.java)
startActivity(intention)
d. Transfert de données scalaires
La fonction putExtra() de la classe Intent permet de transférer des données scalaires d’une activité à l’autre.
Syntaxe
Voici la syntaxe de la fonction putExtra() :
putExtra(<clé>,<valeur>)
Le paramètre clé représente la clé associée à la valeur, elle est utilisée par le composant qui réceptionne l’intent dans le but de récupérer la valeur associée. Le paramètre valeur contient la valeur associée...