Introduction à la programmation sous Android Christophe Renaud M2 Informatique Version 1.1 du 30/09/2015
Objectifs du cours Connaître les bases de la programmation sous Android Environnement de développement (Android Studio) Architecture d'une application Modèle d'exécution
Plan du cours Introduction Architecture d'une application Android Les activités Définir une interface graphique
Android (1) Système d'exploitation à destination des dispositifs mobiles Téléphones, tablettes, téléviseurs, montres, lunettes, voitures Caractéristiques : Opensource (licence Apache), gratuit, flexible Basé sur un noyau linux Inclus les applications de base (téléphone, sms, carnet d'adresse, navigateur, etc.) Un ensemble important d'api (OpenGL, media, etc ) Un SDK basé sur un sous-ensemble de JAVA (autres langages disponibles : C, C++, ) Une machine virtuelle (Dalvik) qui exécute la majorité des applications Remplacée par ART depuis la version 5.0 d'android
Android (2) Historique : Créé en 2005 par la société Android Rachat en 2007 par Google 16 versions depuis la 1.0 (Apple Pie) en 2007 jusqu'à la 5.1.1 (Lollipop) en 2015. Source : developer.android.com
Android (3) Pourquoi développer des applications mobiles? Source : http://www.journaldunet.com/ebusiness/internet-mobile/nombre-abonnes-mobile-monde.shtml Device Type 2014 2015 2016 2017 Traditional PCs (Desk-Based and Notebook) 277,118 252,881 243,628 236,341 Ultramobile (Premium) 36,699 53,452 74,134 90,945 PC Market 313,817 306,333 317,762 327,285 Ultramobiles (Tablets and 227,08 236,778 257,985 276,026 Clamshells) source : (mars 2015) http://www.gartner.com/newsroom/id/3010017
Android (4) Pourquoi développer sous Android? Worldwide Smartphone Sales to End Users by Operating System in 2Q15 (Thousands of Units) Operating System 2Q15 Units 2Q15 Market Share (%) 2Q14 Units 2Q14 Market Share (%) Android 271,01 82.2 243,484 83.8 ios 48,086 14.6 35,345 12.2 Source: Gartner (August 2015) 8,198 2.5 8,095 2.8
Plan du cours Introduction Introduction Architecture d'une application Android Les activités Définir une interface graphique
Schéma de développement Fichiers source (java) xml xml compilateur Fichier apk (Android Package) périphériques Fichiers de ressources
La compilation Compilation Fichiers source (java) Bytecode.class Binaire Dalvik.dex xml xml Fichiers de ressources Jusque 4.4 : interpréteur Dalvik + JIT compilation de parties «critiques» À partir de 5.0 : ART (compilation en code natif Sur le support)
Architecture d'un projet Dossier du projet Sources Java Mises en page Menus Les ressources Icônes Données «constantes» (sous Android Studio)
Les éléments d'une application Une application = {composants} Les composants : Existent de manière indépendante Vus comme autant de points d'entrée par le système Pas de «main» dans une application Liés au design d'android : Toute application doit pouvoir démarrer un composant d'une autre application (sous réserve de droits) et récupérer ses «résultats»
Exemple Mon application = effets sur un portrait de l'utilisateur Difficulté : écrire le code de gestion de l'appareil embarqué Android : démarrage d'un composant existant permettant la prise de vue Récupération de l'image Mon application Problèmes de droits Composant prise de vue «intent» (message asynchrone) Système
Les composants Les activités (Activity) Un écran avec une interface utilisateur et un contexte Les services (Service) Composant sans écran, qui tourne en fond de tâche (lecteur de musique, téléchargement,...) Les fournisseurs de contenu (ContentProvider) I/O sur des données gérées par le système ou par une autre application Des récepteurs d'intentions (BroadcastReceiver) Récupération d'informations générales (arrivée d'un sms, batterie faible,...)
Les interactions Les intentions (Intent) Permet à un composant d'indiquer ce qu'il sait faire ou de rechercher un savoir-faire Les filtres d'intentions (<intent-filter>) Permet de choisir la meilleure application pour un savoir-faire
AndroidManifest.xml Description de l'application Liste des composants Niveau minimum de l'api requise Liste des caractéristiques physiques nécessaires Évite d'installer l'application sur du matériel non compatible (gestion de la visibilité sur Google Play) Liste des permissions dont l'application a besoin Liste des autres API nécessaires ex. Google Map Etc. Généré automatiquement par Android Studio
Exemple <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="fr.univ_littoral.renaud.bidon" > <application android:allowbackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/apptheme" > <activity android:name=".mainactivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.main" /> <category android:name="android.intent.category.launcher" /> </intent-filter> </activity> </application> </manifest>
Les ressources Ressources = toutes les données (autres que le code) utilisées par l'application Rangées dans le dossier res, puis incluses dans l'apk res/drawable et res/mipmap (images en différentes résolutions) Layout (description en XML des interfaces) Menus (description en XML des menus) Values (définitions en XML des constantes utilisées par l'application : chaînes, tableaux, valeurs numériques, etc.)
Strings.xml Fichier ressources, contenant toutes les chaînes constantes Principalement utilisées pour l'interface Type de la constante <resources> <string name="app_name">myapplication</string> <string name="hello_world">hello world!</string> <string name="action_settings">settings</string> </resources> Nom de la constante (permet l'appel depuis l'application ou un autre fichier XML) Valeur de la constante
Internationalisation Objectif : Disposer de plusieurs versions des textes, libellés, etc utilisés par l'application Choix automatique des textes en fonction de la configuration du périphérique Principe Dupliquer le fichier strings.xml : 1 version par langue supportée Stocker chaque version dans un dossier spécifique values-xx (ex. values-en, values-fr, ) Géré via Android Studio app/ res/ values/ strings.xml values-en/ strings.xml values-fr/ strings.xml
La classe R Classe générée par l'ide Permet l'accès aux ressources Créée à partir de l'arborescence présente dans le dossier res Elle contient des classes internes dont les noms correspondent aux différents types de ressources (drawable, layout, ) Elle contient des propriétés permettant de représenter l'ensemble des ressources de l'application Utilisation en Java : R. type.identificateur <resources> <string name="app_name">myapplication</string> <string name="hello_world">hello world!</string> <string name="action_settings">settings</string> </resources> R.string.app_name R.string.hello_world R.string.action_settings
Référencement des ressources en XML Forme générale : @type/identificateur @string/app_name <resources> <string name="app_name">myapplication</string> <string name="hello_world">hello world!</string> <string name="action_settings">settings</string> </resources> @string/hello_world @string/action_settings
Plan du cours Introduction Introduction Architecture d'une application Android Les activités Définir une interface graphique
Les activités (1) Un composant d'une application, doté d'une interface graphique (IHM) et d'un contexte Une activité à la fois visible de l'utilisateur Pour une même application Pour des applications différentes Empilement des activités Démarrage activité 2 Démarrage activité 3 Activité d'avant plan Activité 1 Activité 2 Activité 3 Activité 3 Activité 2 Pile d'activités Activité 1 Activité 2 Activité 1 détruite Activité 1
Les activités (2) Cycle de vie Une activité peut se trouver dans différents états en fonction des actions du système et/ou de l'utilisateur : Active : après un appel à onresume() Suspendue : après un appel à onpause() Arrêtée : après un appel à onstop() Terminée ; après un appel à ondestroy()
Les activités (3) Développement Une classe java par activité ; Les ressources associées (layout, menu, etc.) La classe hérite de la classe Activity Génération d'un code minimum par défaut sous Android Studio public class Bidon extends Activity { @Override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.bidon); } }
Les activités (4) D'autres méthodes peuvent être surchargées, en précisant ce qui doit être fait quand : protected void ondestroy() : l'activité se termine protected void onstart() : l'activité démarre (ou redémarre) protected void onpause() : l'activité n'est plus au premier plan protected void onresume() : l'activité revient au premier plan protected void onstop() : l'activité n'est plus visible protected void onrestart() : l'activité redevient visible
Les activités (5) Destruction de l'application par le système Cas normal : l'activité est terminée. Le système récupère les ressources, en particulier la mémoire Cas spéciaux : suppression d'une activité non active pour des raisons : de limites des ressources ; de changement d'orientation de l'écran. Le système doit sauvegarder l'état de l'activité, pour pouvoir la redémarrer dans son état courant Sauvegarde dans un objet Bundle : couples (nom_donnée, valeur) Contient les données utilisées par l'interface par défaut Systématique dès que l'activité n'est plus visible Surcharge des méthodes de sauvegarde et restauration si d'autres données doivent être sauvées
Les activités (6) void onsaveinstancestate(bundle outstate) Source : develop.android.com void oncreate(bundle saveinstancestate) void onrestoreinstancestate(bundle savedinstancestate)
Plan du cours Introduction Introduction Architecture d'une application Android Les activités Définir une interface graphique
Quelques règles de base Interface = seul contact de l'utilisateur Faire attirant Faire simple L'application doit être intuitive Éviter les trop longs messages Faire ergonomique L'enchaînement des activités doit être rapide L'utilisateur doit toujours connaître l'état courant de l'activité Conseils et «matériels» : http://developer.android.com/design/index.html
Définir une interface graphique Définir les «interacteurs» Objets graphiques visibles par l'utilisateur pour : L'affichage (texte, images, etc.) L'interaction (boutons, cases, champs de saisie, etc. ) Définir leur mise en page Positions dans l'interface (fixes ou relatives) XML ou Java (sauf traitement de l'interaction : Java seul) Privilégier XML Souplesse de mise à jour Permet la prise en compte simplifiée de différents types d'écran
Représentation d'une interface Représentation arborescente Conteneurs invisibles, précisant l'organisation de leurs nœuds fils : les «Layouts» Source : developer.android.com Objets graphiques permettant l'interaction (boutons, zones de texte, etc.) : les Widgets
Les Layouts (1) Zone invisible assurant l'organisation automatique des composants graphiques Peuvent être déclarées en XML ou Java Privilégier XML Séparation du code et de la mise en page Souplesse d'adaptation à différents périphériques Possèdent des propriétés «intuitives» permettant l'organisation des composants Nombreux layouts différents Peuvent être imbriqués (cf arborescence) Un layout doit être chargé dans oncreate() setcontentview(r.layout.nom_du_layout)
Les Layouts (2) Gestion multi-écrans Différentes tailles small, normal, large,xlarge Différentes densités de pixels low (ldpi), medium (mdpi), high (hdpi), extra high (xhdpi) Prévoir un layout par taille (et orientation) de l'écran si nécessaire effets de positionnements relatifs pouvant être gênants Prévoir des images en différentes résolutions
Les Layouts (3) Fonctionnement similaire à l'internationalisation Un sous-dossier spécifique à chaque layout et/ou à chaque image MyProject/ res/ layout/ main.xml layout-land/ main.xml layout-large/ main.xml layout-large-land/ main.xml # default (portrait) # landscape # large (portrait) # large landscape MyProject/ res/ drawable-xhdpi/ awesomeimage.png drawable-hdpi/ awesomeimage.png drawable-mdpi/ awesomeimage.png drawable-ldpi/ awesomeimage.png Source : developer.android.com
RelativeLayout (1) Layout par défaut pour un nouveau projet Positionnement des noeuds par rapport au parent ou les uns par rapport aux autres noeud3 (à droite du nœud 2) noeud1 noeud2 (sous le nœud 1) - match_parent : S'adapte à la taille du conteneur parent (ici l'écran) - wrap-content : s'adapte à la taille de ce qu'il contient (ici deux zones de texte) - dimension fixe
RelativeLayout (2) Comportement par défaut : Tous les noeuds sont positionnés à partir du coin supérieur gauche Superposition!!
RelativeLayout (3) Attributs de positionnement par rapport au parent : android:layout_centerhorizontal android:layout_centervertical android:centerinparent... (cf RelativeLayout.LayoutParams)
RelativeLayout (4) Attributs de positionnement par rapport aux autres nœuds : android:layout_below android:layout_above android:layout_toleftof android:layout_torightof (cf RelativeLayout.LayoutParams) Nécessité de nommer les nœuds Permet de préciser le nœud à partir duquel on se positionne
LinearLayout (1) Aligne les nœuds dans une seule direction horizontale (par défaut) verticale
LinearLayout (2) Modification du «poids» de chaque nœud Permet de changer la taille de la zone occupée par chaque nœud dans l'écran Ajout d'un attribut android:layout_weight à chaque nœud 0 (par défaut) : n'utilise que la zone nécessaire au nœud n>0 : poids du nœud par rapport aux autres nœuds noeud 0 Poids = 0 noeud 1 Poids = 1 nœud 2 Poids = 2 œud 3 Poids = 1 noeud 0 noeud 1 noeud 2 25 % 50 % Répartition au prorata du poids noeud 3 25 %
LinearLayout (3) Exemple 40 % 20 % 40 %
LinearLayout (4) Alignement de chaque noeud dans sa zone Ajout d'un attribut android:layout_gravity Nombreuses valeurs possibles : center, center_vertical, center_horizontal left, right, top, bottom Etc. (cf LinearLayout.LayoutParams)
LinearLayout (5) Exemple
Remarque Possibilité d'organiser visuellement les layouts sous Android Studio
Les Widgets Composants graphiques visibles par l'utilisateur Widgets simples : zones de texte, boutons, listes, etc. Widgets plus complexes : horloges, barres de progression, etc. Héritent de la classe View Utilisation : Définition en XML (type, taille, centrage, position, etc.) Comportement en Java Peuvent également être créés dynamiquement en Java
Les TextView Widget permettant l'affichage d'un texte Normalement non éditable Exemple : <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/letexte" android:hint="texte initial" android:layout_gravity="center" android:gravity="center" /> Nombreux autres attributs Cf classe TextView
Les EditText Widget permettant la saisie d'un texte (TextFields) Accès : ouverture d'un clavier pour la saisie nombreux attributs permettant l'aide à la saisie <EditText android:id="@+id/email_address" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="@string/email_hint" android:inputtype="textemailaddress" /> "text" : Normal text keyboard. "textemailaddress" : Normal text keyboard with the @ character. "texturi" : Normal text keyboard with the / character. "number" : Basic number keypad. "phone" : Phone-style keypad. Source : developer.android.com
Les Button Widget représentant un bouton d'action Renvoie un événement lors de l'appui Peut contenir un texte, une image ou les deux Exemples : <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button_text"... /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button_text" android:drawableleft="@drawable/button_icon"... /> <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/button_icon"... /> Source : developer.android.com
En vrac... Quelques autres widgets Source developer.android.org Spinner RadioButton CheckBox ToggleButton Switch (android 4.0+)
Implantation du comportement (1) Les fichiers XML ne permettent que de : positionner les composants ; définir leurs caractéristiques. Nécessité de : définir leur comportement type d'interaction (clic court, clic long, etc.) code de prise en compte (Java) lier composant et code XML : attribut android:onclick Java : instancier un event listener
Implantation du comportement (2) Attribut android:onclick Doit être suivi du nom de la méthode à appeler en cas de déclenchement Prototype : public void nomdelamethode(view mavue) <Button android:id="@+id/monbouton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/montexte" android:onclick="onboutonclique" /> public void onboutonclique(view mavue) { } System.out.println("le bouton a été cliqué") ; Permet de récupérer des informations sur le composant graphique qui a généré l'événement mavue.getid() R.id.monBouton
Implantation du comportement (3) Les event listener interfaces de la classe View ne disposent que d'une seule méthode à implanter méthode appelée quand le composant associé est déclenché par l'utilisateur Exemples : interface méthode View.OnClickListener abstract void onclick(view v) View.OnLongClickListener abstract boolean onlongclick(view v) View.OnFocusChangeListener abstract void onfocuschange(view v, boolean hasfocus)
Implantation du comportement (3) Exemple : l'interface View.onClickListener public void onclick(view v)... Button button = (Button) findviewbyid(r.id.button_name); button.setonclicklistener(new View.OnClickListener() { });... public void onclick(view v) { // Do something in response to button click } Source : developer.android.com