Android : Introduction au développement d'applications JAVA

25 juillet 2012 rdorigny 0 commentaires

Android est un système d'exploitation pour mobiles/tablettes très en vogue basé sur Linux. Initialement développé par la société Android, et depuis 2005 par le géant américain Google.

Google propose un kit de développement en JAVA pour les applications mobiles. ainsi qu'une machine virtuelle machine compatible appelée JVM (JAVA Virtual Machine) de Dalvik.

A la différence d'un développement JAVA classique, la mobilité propose des contraintes que la JVM doit prendre en compte comme des limitations matériels (processeur peu performant, faible capacité mémoire, autonomie limitée).


1)Présentation générale

Android est un Operating System qui ne cesse d'évoluer, en quatre années prés d'une quinzaine de versions sont apparues. Cela demande aux développeurs de s'adapter aux nouvelles versions par de nombreux tests multi-plateforme et de faire en sorte que le code soit supporté entre les différentes versions de l'API.

Nom

API

Version

Date de sortie

Jelly Bean 16 4.1 Juillet 2012
Ice Scream Sandwich 14-15 4.0 Octobre 2011
Honeycomb 11-13 3.0-3.2 Février-Juillet 2011
Gingerbread 9-10 2.3 Décembre 2010
Froyo 8 2.2 Mai 2010
Eclair 7 2.0-2.1 Octobre 2009
Donut 4 1.6 Septembre 2009
Cupcake 3 1.5 Avril 2009
1.0-1.1 1-2 1.1 Septembre 2008

La version 3 est dédiée aux tablettes, et depuis la version 4, Android est compatible sur les deux plateformes (téléphone & tablette). A noter que Android supporte un grand nombre de taille d'écrans entre le QVGA 240x320 (Quarter Video) au WXGA800 en 800x1280 (Wide Video).

L'architecture du système est basé sur une couche Linux qui fait l'interface entre le matériel et les couches applicatives. Pour les couches applicatives, on distingue :
  • les librairies C/C++ qui permettent l’accès directe aux systèmes,
  • le runtime (JVM de Dalvik) permet l’exécution des applications JAVA,
  • le framework Android qui propose l'environnement applicatifs, les bibliothèques JAVA, les interfaces (activités, vue, ...),
  • l'application codée en JAVA.


  • Les composants d'applications:
  • Les activités sont associées à une vue/écran de l'application. Le programme principale est aussi appelé activité principale ou encore thread principale,
  • Les intentions permettent de lancer d'autres activités par l'intermédiaire du framework qui gère les demandes applicatives. Il existe deux types d'intentions : les intentions explicites pour réclamer l'activation d'une classe particulière, et les intentions implicites qui sont appelées pour lancer des actions sans nommer la classe explicitement,
  • Les services permettent de lancer des opérations en arrière plan. Ils ne sont pas rattachés à une vue. Exemple : Accès à des fichiers, appel de services web,
  • Le content provider ou fournisseur de contenu permet d'accéder aux data ou de partager des données entre activités,
  • Le broadcast receiver ou récepteurs est chargé de répondre aux messages système.

  • Le framework gère le cycle de vie de l'application selon les événements et les ressources matériels. Cela permet de ne pas donner accès à des fonctions critiques aux développeurs et donc de gérer les erreurs, les problèmes de ressources, ...


    2)Les activités

    Lors de l'ouverture de l'application la JVM créé un processus Linux, le processus initial est lié au lancement de l'activité initiale. Les activités sont associées à une vue (view). Il est alors possible de lancer d'autres activités par le biais des intentions, et le framework gère les intentions qui lui sont proposées.

    Il est possible de lancer plusieurs activités simultanément, le système les empile alors dans une pile appelée Back stack, de la sorte que l'activité la plus récente soit sur le dessus de la pile (et donc c'est elle qui sera visible).


    A noter que la pression sur bouton de retour/back termine l'activité dite courante.

    Le cycle de vie de l'activité:
    Les activités disposent d'un cycle définit comme le schéma ci-dessous, c'est le framework qui gère Plusieurs états sont définis :
  • onResume(): L'application est en cours d’exécution et visible en premier plan,
  • onPause(): L'activité est en cours d'exécution mais en dessous des autres,
  • onStop(): L'activité est stoppé mais reste en vie en cas de rappel.


  • 3)Premier programme

    Pour créer un sa première application Android, vous pouvez faire sous Eclipse : Menu File , New, Android Project (Mettre un nom au programme), choisir la machine AVD qui correspondra à votre plateforme de test, préciser le nom du package, Finish. Pour lancer, sur le projet choisir Runs as, Run configuration..., préciser la target AVD. L'émulateur se lance, prenez votre mal en patience, c'est assez long. AVD est gourmand en ressource, n'hésitez à gonfler la RAM de votre station de travail.

    Si on regarde le code, on observe que pour créer une activité, il faut :
    1)Créer une classe qui hérite de la classe android.app.Activity en surchargeant la méthode onCreate(),
    2) Appeler le super constructeur de création d'activité,
    3) Associer la view à l'activité,
    4) Surcharger les autres méthodes du cycle de vie.

    A noter un fichier important, le fichier AndroidManifest.xml qui précise les différents éléments du programme. La définition est obligatoire dans ce fichier. Les éléments non définis ne seront pas pris en compte.

    La moindre erreur dans ce fichier provoque un arrêt de l'exécution du programme.

    Donc le premier programme FirstActivity.java ressemble à:
    package fr.doritique; import android.app.Activity; import android.os.Bundle; public class FirstActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } }
    Avec AndroidManifest.xml :
    <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="fr.doritique" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="15" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:name=".FirstActivity" 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>

    Avec String.xml :
    <?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">Hello World, FirstActivity!</string> <string name="app_name">First</string> </resources>

    Avec Main.xml :
    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> </LinearLayout>

    Surcharge des méthodes du cycle de vie:
    Notons que dans l'exemple précédent, nous avons surchargé la méthode onCreate() pour ajouter nos fonctionnalités. C'est ainsi que l'on peut surcharger les méthodes liées au cycle de vie de l'application, c'est à dire:
  • onCreate : appelée lors de la création de l'activité. A noter le paramètre savedInstanceState qui permet de restaurer l'état de l'activité,
  • onDestroy : appelée pour terminer proprement une activité. Nous y trouverons notamment les fermetures d'accès fichiers, libération de mémoires et autres si besoin,
  • onStart : appelée au démarrage d'une activité, utilisée pour la phase d'initialisation,
  • onStop : appelée lorsque l’activité passe en arrière plan,
  • onRestart : appelée au réveil de l'activité,
  • onPause : appelée au lorsque l'activité est suspendue et passera en arrière plan, il faut prendre soins d’arrêter les actions trop gourmandes pour libérer des ressources au système,
  • onResume : appelée suite au démarrage ou après une pause, permet de relancer les threads,
  • onSaveInstanceState : pour sauvegarder l'état d'une activité, ce qui permettra de le restaurer au réveil
  • onRestoreInstanceState : appelée pour recharger l'état d'une activité et de l'interface,

  • 4) Les services et les intentions

    Android fonctionne sur des plateformes qui seront très limitées en terme de ressources, il ne faut donc pas exécuter de tâche trop gourmande dans le thread principal sous peine d'avoir une erreur ANR (Application Not Responding). Pour cela, on utilisera les services qui dédiés aux tâches de fond pour traiter les opérations coûteuses et longues.

    Mais c'est le framework qui gérera les intentions, en effet il faudra passer par une intention qui propose le service. Le système selon des critères liés aux ressources lancera ou non la demande de service.

    Donc, on créé une classe spécifique qui hérite de IntentService dans laquelle on surcharge les méthodes onCreate et onHandleIntent. La sous-classe IntentService se chargera de lancer le thread dédié au service. Le coeur du service doit être placé dans onHandleIntent(Intent intent).

    Pour lancer le service, il faut demander au framework de l'exécuter en créant une intention et en lui donnant la classe à lancer. Ensuite, on appelle startService() pour un service et startActivity() pour une activité.


    Avec ExpensesListActivity.java :
    package com.ltree.expenses; import android.app.Activity; import android.content.Intent; import android.os.Bundle; public class ExpensesListActivity extends Activity { @SuppressWarnings("unused") private static final String TAG="ExpensesListActivity"; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); startSync(); } private void startSync() { Intent startSyncService = new Intent(this, SyncService.class); startService(startSyncService); } }
    Et avec SyncService.java :
    package com.ltree.expenses; import android.app.IntentService; import android.content.Intent; import android.util.Log; public class SyncService extends IntentService { private static final String TAG="SyncService"; @Override public void onCreate() { super.onCreate(); Log.i(TAG, "onCreate() called"); } public SyncService() { super("SyncService"); } @Override protected void onHandleIntent(Intent intent) { Log.i(TAG, "Processing started"); try { Thread.sleep(30000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } Log.i(TAG, "Processing finished"); } }

    Et dans logcat on trouve :
    07-22 21:22:24.913: I/SyncService(1412): onCreate() called 07-22 21:22:24.913: I/SyncService(1412): Processing started 07-22 21:22:54.924: I/SyncService(1412): Processing finished

    L'API Log:
    La classe android.util.Log propose plusieurs méthodes qui permettent la journalisation. Il existe plusieurs types de journalisation :
  • v : verbeux
  • d : debug
  • w : warning
  • e : error
  • i : information

  • On peut ainsi faire du log dans le logcat (gestionnaire d’évènements).La syntaxe est de la forme :
    private static TAG final="Nom de la classe en général"; Log.i(TAG,"Le message à journaliser ds le gestionnaire");

    Le TAG permet de séparer les différents niveaux de log, les logs debug et verbeux n'ont pas vocation à rester, ils sont utilisés uniquement durant la période de de développement.

    5)Les ressources


    Les ressources sont des fichiers externes utilisés par l'application, on les retrouve dans le projet sous le répertoire res.

    Le concept des ressources est de rendre modulaire le code au maximum, sous la forme de plusieurs fichiers qui décriront les variables du programme, la mise en page des vues (layout), des images...

    On trouve :
  • res/drawable : rassemble les fichiers images,
  • res/layouts : rassemble les fichiers de mise en pages,
  • res/values : rassemble les fichiers xml qui définissent des variables (string.xml, arrays.xml, ...),
  • res/raw : les variables non retouchés,
  • res/xml : des fichiers xml pris en charge par la fonction ressources.getXML pour la conversion.

  • Lors de la compilation Eclipse générera automatiquement une classe R relative aux ressources. La classe définit les ressources sous forme de variables. Par exemple, R définit une classe R.string et une variable R.string.hello. A chaque modification le fichier R est réadapté automatiquement. On retrouve également la variable R.layout.main qui est chargée lors de la création de l'activité.

    package com.ltree.expenses; public final class R { public static final class attr { } public static final class drawable { public static final int icon=0x7f020000; } public static final class layout { public static final int main=0x7f030000; } public static final class string { public static final int app_name=0x7f040001; public static final int hello=0x7f040000; } }

    Donc pour utiliser ces variables android.R.type.nom_ressource, par exemple:
    //définit l'affichage de l'activité setContentView(R.layout.main);

    Le framework propose un objet ressource qui permet d'accéder aux variables par l'intermédiaire des getters:
    Ressource ressources=getRessources(); String s=ressources.getString(R.string.hello);

    Déclaration de variables en XML:
    Le framework donne la possibilité de définir nos propres variables à l'aide de fichiers XML. Le fichier peut avoir n'importe quel type de variable, mais il est conseillé de les séparer en plusieurs fichiers XML.
    <?xml version="1.0" encoding="utf-8"?> <ressources> <string name="str">mon texte</string> <array> <item>azerty</item> <item>qwerty</item> </array> <color name="couleur">#012231</color> </ressources>

    La syntaxe des variables :
  • String : il est possible de faire des chaines de caractères, attention de bien penser à échapper les guillemets : <string name="str">mon texte</string> et pour l'utilisation en JAVA R.string.str, en XML @[package:]/string/str
  • couleur : il existe plusieurs modèle, le plus complet étant #AARRGGBB (transparence + couleur)de la forme : <color name="couleur">#43012231</color> et pour l'utilisation en JAVA R.couleur.color, en XML @[package:]/color/couleur
  • image nine-patch : pour les images étirables et pour l'utilisation en JAVA R.drawable.fichier, en XML @[package:]drawable.fichier


  • 6)Conclusion

    Nous avons vu les concepts généraux d'une application Android sous JAVA. Ce qu'il est important de comprendre, c'est que Google fournit un framework très complet qui encapsule et encadre le code des développeurs. Il vous suffira d'entrer dans cette philosophie et tout ira pour le mieux.







    Pseudonyme (obligatoire) :
    Adresse mail (obligatoire) :
    Site web :




    © 2017 www.doritique.fr par Robert DORIGNY