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 :




    © 2023 www.doritique.fr par Robert DORIGNY