Android
              JUG Lausanne Janvier 2013


                  Jérôme Van Der Linden




1	


© OCTO 2012
Moi
       !   Architecte Java/JEE @ Octo
              !   Archi, dev, audit, conseil
                                                          Metroide	

              !   jva@octo.com


       !   Développeur Android depuis 2009                Android
              !   Metroide                                Holo
              !   Formateur Octo depuis 2010
                                                          Colors

       !   Auteur de android-holo-colors.com

       !   Co-Inventeur de Appaloosa

       !   Co-Auteur de Robospice
       @jeromevdl	

             +Jérôme Van Der Linden


2	


© OCTO 2012
Plan

       !  La plateforme Android

       !  Les bases du développement

       !  Outillage et écosystème

       !  Bonnes pratiques




3	


© OCTO 2012
Plan

       !  La plateforme Android

       !  Les bases du développement

       !  Outillage et écosystème

       !  Bonnes pratiques




4	


© OCTO 2012
08/2005 11/2007 08/2008 10/2008 05/2009 09/2009 01/2010
        Rachat                              SDK 1.0     SDK 1.5
                               1er SDK
        Startup     OHA                      Market    (utilisable)   SDK 1.6    SDK 2.1
                              public v0.9
        Android                             HTC G1      HTC G2




        05/2010 12/2010 02/2011 10/2011 02/2012 07/2012
                                 SDK 3.0                  Market
          SDK 2.2
           Push
                    SDK 2.3     Tablettes    SDK 4.0      devient      SDK 4.1   ...
                                  only                   PlayStore




5	


© OCTO 2012
Quelques chiffres   nombre d'applications sur Google Play Store




6	


© OCTO 2012
7	


© OCTO 2012
Java

       !   Sous ensemble de l’implémentation Apache Harmony
           !   JavaSE 5


       !   Et aussi ...
           !   Junit (3.8)
           !   Apache commons logging et HttpComponents
           !   Parsers json et xml


       !   Mais ...
           !   Toutes les méthodes des classe Android sont stubés
                !   throw new RuntimeException("Stub");	
           !   Impossible d’exécuter / tester sans émulateur / device




8	


© OCTO 2012
DVM : Dalvik Virtual Machine
                           code                               bytecode                       application

                            .java                     .class                      .dex             .apk
                                        javac                         dx              apkbuilber

                                                                                !   Compilation JIT depuis
                                                                                    Android 2.2

                                                                                !   Pas de génération de
                                                                                    bytcode au runtime
                                                                                     !    runtime weaving KO
                                                                                     !    mais compiletime OK


                                                                                !   Des tentatives de groovy,
                                                                                    scala

                                                                                !   GC mark&sweep
                      https://sites.google.com/site/io/dalvik-vm-internals	




9	


© OCTO 2012
Sécurité
        !   Système basé sur Linux
            !   users, groups, droits... : par défaut l’utilisateur n’est pas root

        !   Sandboxing
            !       Une VM par application
            !       Un user unique par application
            !       Un process unique par application
            !       Un espace dédié du filesystem par application

        !   Permissions
            !   Un ensemble de permissions pour accéder aux différents services
            !   Les permissions sont affichées avant l’installation de l’application

        !   Signature
            !   Les applications sont signées pour être publiées sur le store

        !   Communications
            !   Les applications ne peuvent communiquer entre elles sauf
                     !       Par des Intents
                     !       Si elles utilisent un filesystem commun (ex: SDCard)
                     !       Si elles autorisent explicitement dans le manifest (ContentProviders, Services
                     !       Si elles ont la même signature (partage du même user id)


10	


© OCTO 2012
Plan

    !  La plateforme Android

    !  Les bases du développement

    !  Outillage et écosystème

    !  Bonnes pratiques




11	


© OCTO 2012
Structure d’un projet

                         Classes java


                         Classes de mapping des ressources Android
                         JAR d’Android

                         Ressources « brutes »



                         Ressources mappées par Android :
                         - images (png, xml)
                         -  animation (xml)
                         -  écrans (xml)
                         -  menus (xml)
                         -  media (wav, aac, mp3, H.264, mpeg4, ogg)
                         -  data : textes, styles couleurs, tableaux… (xml)


                          Manifest de l’application




12	


© OCTO 2012
AndroidManifest.xml
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"	                   Identification
     package="com.octo.android.askbob"	
     android:versionCode="1"	                                                            formelle de
     android:versionName="1.0" >	                                                        l’application
        <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="16" />	
        <uses-feature android:name="android.hardware.bluetooth" />	                      Contraintes tech de
                                                                                         l’application
        <uses-permission android:name="android.permission.INTERNET" />	
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />	    Permissions de
        <application	
                                                                                         l’application
            android:allowBackup="true"	
            android:icon="@drawable/ic_launcher"	
            android:label="@string/app_name"	
            android:theme="@style/AppTheme" >	

            <activity	
                android:name=".activity.SplashScreenActivity"	
                android:theme="@android:style/Theme.NoTitleBar" >	                        Contenu de
                <intent-filter>	                                                          l’application :
                    <action android:name="android.intent.action.MAIN" />	
                                                                                          Icône, Nom,
                    <category android:name="android.intent.category.LAUNCHER" />	         Activités, Services
                </intent-filter>	
            </activity>	

            <activity android:name=".activity.OctoDetailActivity" />	

         <service	
                android:name="com.octo.android.askbob.network.AskBobJsonSpiceService"	
                android:exported="false" />	
     </application>	
 </manifest>	




13	


© OCTO 2012
Permissions
        !   130 permissions
           !   internet, gps, bluetooth, contacts, telephone, sms, camera, vibreur,
               état du réseau/wifi, accès a la SD...




14	


© OCTO 2012
Ressources                                         public final class R {	
                                                          public static final class drawable {	
                                                              public static final int ic_dictionary=0x7f020000;	
                                                              public static final int ic_menu_search=0x7f020001;	
                                                          }	
                                                         public static final class layout {	
                                                              public static final int main=0x7f030000;	
                                                              public static final int result=0x7f030001;	
                                                              public static final int word=0x7f030002;	
                                                          }	
                                                          public static final class menu {	
                                                              public static final int options_menu=0x7f080000;	
                                                          }	
                                                         public static final class string {	
                                                              /** The name of the application. 	
                                                               */	
                                                              public static final int app_name=0x7f060000;	
                                                              /** The menu entry that invokes search. 	
                                                               */	
                                                              public static final int menu_search=0x7f060003;	
                                                         }	
                                                         public static final class id {	
                                                              public static final int list=0x7f090001;	
                                                              public static final int text=0x7f090000;	
                                                          }	
                                                          //...	
                                                    }	

                                               R.java
strings.xml                                         <TextView	                                     main.xml
<resources>	                                                     android:id="@+id/text"	
    <!-- The name of the application. -->	                       android:layout_width="fill_parent"	
    <string name="app_name">Dictionary</string>	                 android:layout_height="wrap_content" />	
                                                    <ListView	
    <!-- The menu entry that invokes search. -->	                android:id="@+id/list"	
    <string name="menu_search">Search</string>	                  android:layout_width="fill_parent"	
</resources>	

                                                  android:layout_height="0dp">	




15	


© OCTO 2012
Utilisation des ressources               public final class R {	
                                                public static final class drawable {	
                                                    public static final int ic_dictionary=0x7f020000;	
                                                    public static final int ic_menu_search=0x7f020001;	
                                                }	
                                               public static final class layout {	
                                                    public static final int main=0x7f030000;	
   !   Utilisable dans le code java                 public static final int result=0x7f030001;	
                                                    public static final int word=0x7f030002;	
        !   getResources.getDrawable            }	
                                                public static final class menu {	
            (R.drawable.ic_menu_search)             public static final int options_menu=0x7f080000;	
                                                }	
        !   getResources.getString             public static final class string {	
                                                    /** The name of the application. 	
            (R.string.menu_search)                   */	
                                                    public static final int app_name=0x7f060000;	
                                                    /** The menu entry that invokes search. 	
                                                     */	
   !   Et dans les xml                         }	
                                                    public static final int menu_search=0x7f060003;	

                                               public static final class id {	
        !   @drawable/ic_dictionnary                public static final int list=0x7f090001;	
                                                    public static final int text=0x7f090000;	
        !   @string/menu_search                 }	
                                                //...	
        !   @id/text                      }	

                                               R.java




16	


© OCTO 2012
Layout

        !   Définit la structure visuelle de l’IHM, conteneur d’éléments graphiques
        !   Généralement défini en XML à la XUL
                 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"	
                     android:layout_width="match_parent" android:layout_height="match_parent"	
                     android:orientation="vertical" >	
                     <Button android:id="@+id/button" android:text="@string/button1" 	
                         android:layout_width="wrap_content" android:layout_height="wrap_content" />	
                 </LinearLayout>	



            !   Et récupérable depuis Java :
                  Button button = (Button) findViewById(R.id.button);	





        !   Ou instancié dynamiquement en java à la Swing
            !   Plus rare sauf pour vos propres composants
                  SuperExtendedButton button = new SuperExtendedButton(context);	
                  button.setText(R.string.button1);	
                  layout.addView(button);	





17	


© OCTO 2012
MVC



                         Contrôleur

                          Activity,
                         Fragment
              Modèle                     Vue
              POJO, DB                Layout (XML)




18	


© OCTO 2012
MVC
     public class DetailActivity extends Activity {	

            @Override	
            protected void onCreate(Bundle savedInstanceState) {	
                super.onCreate(savedInstanceState);	

                 setContentView(R.layout.activity_detail);	
                 TextView fullNameTextView = (TextView) findViewById(R.id.detail_fullname);	
            }	
     }	

                                                                                                    activity_detail.xml
       DetailActivity.java                                 <?xml version="1.0" encoding="utf-8"?>	
                                                           <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"	
                                                               android:layout_width="match_parent"	
                                                               android:layout_height="match_parent"	
                                                               android:background="@color/detail_background" >	

                                                               <RelativeLayout	
                                                                   android:layout_width="match_parent"	
                                                                   android:layout_height="match_parent"	
                   Contrôleur                                      android:padding="5dp" >	

                                                                    <TextView	

                    Activity,                                           android:id="@+id/detail_fullname"	
                                                                        style="@style/DetailTitle"	
                                                                        android:layout_width="wrap_content"	
                   Fragment                                             android:layout_height="wrap_content"/>	

                                                                   <Button style="@style/DetailButton"	
Modèle                                      Vue                        android:id="@+id/detail_mobile_button"	
                                                                       android:layout_below="@id/detail_fullname"	
                                                                       android:drawableLeft="@drawable/ic_menu_call" />	
                                                               </RelativeLayout>	
POJO, DB                              Layout (XML)         </ScrollView>	




    19	


    © OCTO 2012
Cycle de vie des activités




!   onSaveInstanceState :
        !   backup des donnés de
            l’écran lors d’un
            changement de
            configuration (rotation de
            l’écran, reception d’un
            appel, ...)




20	


© OCTO 2012
Intents – Navigation entre Activités
        !   Résolution explicite
              !   Spécification d’un composant (class)
                          Intent intent = new Intent(ActivityA.this, ActivityB.class);	

        ActivityA         startActivity(intent);	                                         ActivityB
                          // OU	
                          startActivityForResult(intent, REQUEST_CODE);	



        !   Passage de paramètres
              !   Types primitifs (boolean, int, double, ...) + String
              !   Serializable
              !   Parcelable     intent.putExtra(String key, value);	



        !   Réception des paramètres
                        protected void onCreate(Bundle savedInstanceState) {
                                                                           	
                          super.onCreate(savedInstanceState);	

        ActivityB              getIntent().getStringExtra(key);	
                               getIntent().getParcelableExtra(key2); 	
                               // ...	
                        }	




21	


© OCTO 2012
Parcelable
        public class User implements Parcelable {	
          private String name;	
          private int age;	

               public int describeContents() {	
                  return 0;	
               }	

               public void writeToParcel(Parcel dest, int flags) {	
                  dest.writeString(name);	
                  dest.writeInt(age);	
               }	

               public User(Parcel userParcel) {	
                  name = userParcel.readString();	
                  age = userParcel.readInt();	
               }	

               public static final Parcelable.Creator<User> CREATOR = new Parcelable.Creator<User>()
        {	
                 public User createFromParcel(Parcel in) {	
                    return new User(in);	
                 }	
                 public User[] newArray(int size) {	
                    return new User[size];	
                 }	
               };	
        }	





22	


© OCTO 2012
Intents – Navigation dans le système
        !   Résolution implicite
             !   Via une action
             !   Exemple: partager du contenu
   Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);	
   sharingIntent.setType("text/plain");	
   sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Subject Here");	
   sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, "Content to share");	
   startActivity(Intent.createChooser(sharingIntent, "Share via"));	




        !   Rendre son application réceptive à un Intent
             !   Via les intent-filter : action + category + data
        <activity android:name="ShareActivity" >	
            <intent-filter>	
                 <action android:name="android.intent.action.SEND" />	

                 <category android:name="android.intent.category.DEFAULT" />	

                 <data android:mimeType="text/plain" />	
                 <data android:mimeType="image/*" />	
             </intent-filter>	
        </activity>	





23	


© OCTO 2012
Événements
        !   onClick
            !   Disponible depuis le SDK 1.6, auparavant, il fallait définir un
                OnClickListener...
   <Button	                                    layout                                                activity
       android:id="@+id/button"	                             public void onButtonClick(View v) {	
       android:layout_width="wrap_content"	                       // do something	
       android:layout_height="wrap_content"	                 }	

          android:onClick="onButtonClick"        />	




        !   Listeners
            !       OnClickListener               textview.setOnKeyListener(new OnKeyListener() {	

            !       OnFocusChangeListener           @Override	
                                                    public boolean onKey(View v, int keyCode, KeyEvent event)	
            !       OnKeyListener                   {	
                                                         // do something	
            !       OnDragListener                       return false;	
                                                    }	
            !       OnCheckedChangeListener       });	


            !       OnMenuItemClickListener
            !       OnItemSelectedListener
            !       ...

24	


© OCTO 2012
LinearLayout

        !   Alignement Horizontal ou Vertical

        <?xml version="1.0" encoding="utf-8"?>	
        <LinearLayout xmlns:android="http://schemas.android.com/
        apk/res/android"	
            android:layout_width="match_parent"	
            android:layout_height="match_parent"	
            android:orientation="vertical" >	

            <Button	
                android:id="@+id/button1"	
                android:layout_width="wrap_content"	
                android:layout_height="wrap_content"	
                android:text="@string/button1" />	

            <Button	
                android:id="@+id/button2"	
                android:layout_width="wrap_content"	
                android:layout_height="wrap_content"	
                android:text="@string/button1" />	

            <Button	
                android:id="@+id/button3"	
                android:layout_width="wrap_content"	
                android:layout_height="wrap_content"	
                android:text="@string/button1" />	

        </LinearLayout>	





25	


© OCTO 2012
RelativeLayout
        !   Positionnement relatif
         <?xml version="1.0" encoding="utf-8"?>	
         <RelativeLayout xmlns:android="http://
         schemas.android.com/apk/res/android"	
             android:layout_width="match_parent"	
             android:layout_height="match_parent" >	

             <Button	
                 android:id="@+id/button1"	
                 android:layout_width="match_parent"	
                 android:layout_height="wrap_content"	
                 android:text="@string/button1" />	

             <Button	
                 android:id="@+id/button2"	
                 android:layout_width="wrap_content"	
                 android:layout_height="wrap_content"	
                  android:layout_below="@id/button1"	
                  android:layout_alignLeft="@id/button1"	
                  android:text="@string/button2" />	

             <Button	
                 android:id="@+id/button3"	
                 android:layout_width="match_parent"	
                 android:layout_height="wrap_content"	
                  android:layout_toRightOf="@id/button2"	
                  android:layout_below="@id/button1"	
                  android:text="@string/button3" />	

         </RelativeLayout>	





26	


© OCTO 2012
TableLayout
        <?xml version="1.0" encoding="utf-8"?>	
        <TableLayout xmlns:android="http://
        schemas.android.com/apk/res/android"	
            android:layout_width="match_parent"	
            android:layout_height="match_parent" >	

            <TableRow>	
                <Button	
                    android:id="@+id/button1"	
                    android:layout_width="match_parent"	
                    android:layout_height="wrap_content"	
                    android:text="@string/button1" />	

                <Button	
                    android:id="@+id/button2"	
                    android:layout_width="wrap_content"	
                    android:layout_height="wrap_content"	
                    android:text="@string/button2" />	
            </TableRow>	
            <TableRow>	
                <Button	
                    android:id="@+id/button3"	
                    android:layout_width="wrap_content"	
                    android:layout_height="wrap_content"	
                    android:text="@string/button3" />	

                <Button	
                    android:id="@+id/button4"	
                    android:layout_width="match_parent"	
                    android:layout_height="wrap_content"	
                    android:text="@string/button3" />	
            </TableRow>	

        </TableLayout>	





27	


© OCTO 2012
Conteneurs (!= layout)

        ListView          TabView




                                           MapView
                     WebView



          GridView




                              ScrollView



28	


© OCTO 2012
Listes
        !   Listview
                                <ListView	
                                       android:id="@android:id/list"	
                                       android:layout_width="fill_parent"	
                                       android:layout_height="fill_parent" />	


        !   Utilisation d’Adapters pour populer la liste
                !   Idem pour les Gridview
                !   listview.setAdapter(myAdapter);	

        !   BaseAdapter, ArrayAdapter, CursorAdapter
         public class MyAdapter extends BaseAdapter {	
             public int getCount() {} // return cell number	
             public Object getItem(int position) {} // return model object for the cell	
             public long getItemId(int position) {} // return cell object id (position)	

                public View getView(int position, View convertView, ViewGroup parent) {	
                   View cell = null;	
                   if (convertView == null) { 	
                       // create view by inflating layout for the cell here	
                   }	
                   else {	
                      cell = convertView; // recycle an older cell	
                   }	
                   // set cell attributes here	
                   return cell;	
                }	
         }	



29	


© OCTO 2012
Composants graphiques
                        Checkbox

 Button



   ProgressBar
                        Radio


   Switch



              Spinner


                                         SeekBar




                                Picker    Dialog




30	


© OCTO 2012
Adoptez votre propre style
        !   Soit le champ texte suivant :
            <TextView	
                   android:layout_width="fill_parent"	
                   android:layout_height="wrap_content"	
                   android:text="@string/hello"	
                   android:textColor="#00FF00"	
                   android:typeface="monospace" />  	

        !   On peut extraire le style suivant :
            <resources>	
               <style name="CodeFont" parent="@android:style/TextAppearance.Medium">	
                   <item name="android:layout_width">fill_parent</item>	
                   <item name="android:layout_height">wrap_content</item>	
                   <item name="android:textColor">#00FF00</item>	
                   <item name="android:typeface">monospace</item>	
               </style>	
            </resources>	

        !   Et réduire ainsi le champ texte à :
           <TextView	
                   style="@style/CodeFont"	
                   android:text="@string/hello" />	



        !   Mais surtout le rendre disponible à d’autres champs textes sans
            dupliquer des lignes et des lignes de propriétés


31	


© OCTO 2012
Héritage des styles
        !   Héritage d’un style système
              <style name="GreenText" parent="@android:style/TextAppearance">	
                  <item name="android:textColor">#00FF00</item>	
              </style>	




        !   Héritage d’un style défini
              <style name="CodeFont.Red">	
                  <item name="android:textColor">#FF0000</item>	
              </style>	


              <style name="CodeFont.Red.Big">	
                  <item name="android:textSize">30dp</item>	
              </style>	



        !   Surcharge
              <style name="CodeFont.Red.Dark">	
                  <item name="android:textColor">#FF6611</item>	
              </style>	




32	


© OCTO 2012
Theme = ∑ styles

        !   Un thème est un ensemble de styles appliqués à toute l’application ou à
            une activité entière
        !   Définition dans le fichier AndroidManifest.xml
            <application	
                   android:allowBackup="true"	
                   android:icon="@drawable/ic_launcher"	
                   android:label="@string/app_name"	
                 android:theme="@android:style/Theme.Holo.Light" >	

            <activity	
                   android:name=".activity.SplashScreenActivity"	
                   android:theme="@android:style/Theme.NoTitleBar" />	





        !   Depuis Honeycomb, Thème Holo (inspiré du film Tron)
            !   basé sur la couleur bleu #33b5e5
        !   Pensez à étendre le style Holo ou Holo.Light pour vos thèmes
            <style name="CustomTheme" parent="android:Theme.Holo.Light">	
                <item name="android:windowBackground">@color/custom_theme_color</item>	
                <item name="android:colorBackground">@color/custom_theme_color</item>	
            </style>	





33	


© OCTO 2012
Plan

   !  La plateforme Android

   !  Les bases du développement

   !  Outillage et écosystème

   !  Bonnes pratiques




34	


© OCTO 2012
Développement

        !   SDK Android
           !       Windows / Mac / Linux
           !       SDK Manager (« android »)
           !       Tools
           !       Platform-tools
           !       Sources




35	


© OCTO 2012
Eclipse + ADT

 !   Android Developer Tools (ADT)
        !       Création, compilation, debug, packaging
        !       Auto complétion dans le XML
        !       Editeur WYSIWYG
        !       DDMS, analyse des devices :
                 !       thread,
                 !       mémoire,
                 !       filesystem,
                 !       simulation d’appels, de SMS, de GPS, ...
        !   Logcat
                 !   accès aux logs des devices




36	


© OCTO 2012
IntelliJ

   !   Support natif d’Android
        !   Même fonctionnalités que ADT


   !   Éditeur WYSIWYG depuis la v12 :




37	


© OCTO 2012
SDK Tools

        !   android
            !   Permet de télécharger les différentes versions du SDK (SDK Manager)
            !   Permet de créer des projets Android
            !   Permet de créer des images AVD (Android Virtual Device)

        !   emulator
            !   Emule les images AVD
            !   Permet de tester/debugger
                l’application

        !   adb (Android Debug Bridge)
            !   Permet d’installer des apk (Android PacKage) sur le device
            !   Permet de copier des fichiers sur le device
            !   Permet d’exécuter des commandes shell sur le device


38	


© OCTO 2012
SDK Tools

        !   Lint
            !   Analyse du code Android (~ PMD/Findbugs Android)
            !   Intégré à Eclipse et IntelliJ

        !   hierarchyviewer
            !   Permet de visualiser l’arbre des vues pour optimiser les perfs de l’UI

        !   draw9patch
            !   Permet de créer des png « extensibles »
                   !   Fichier « .9.png »

        !   traceview
            !   Profiling d’une application en cours d’exécution




39	


© OCTO 2012
Librairies
              !   Roboguice: Google guice pour Android
                  !   Injection de dépendances
                  !   Injection de view...

              !   Spring Android
                  !   RestTemplate pour faciliter les appels de
                      services HTTP/REST


              !   Robospice
                  !   Traitements réseaux asynchrones
                  !   Mise en cache


              !   Ormlite
                  !   ORM léger pour Sqlite



40	


© OCTO 2012
Librairies
                          !   ActionBarSherlock
                               !   Mise à disposition des ActionBar sur les
                                   Android < 3.0


                         !   HoloEverywhere
                               !   Mise à disposition du thème Holo pour les
                                   Android < 3.0


                          !   Android Asset Studio & Android Holo Colors
                               !   Création d’icônes, d’images (holo), de fichiers
                                   de styles, ...

        !   Et des dizaines d’autres disponibles sur
              !   http://www.theultimateandroidlibrary.com/
              !   http://www.openintents.org/en/libraries
              !   http://www.androidviews.net/

41	


© OCTO 2012
Et mes librairies Java ?

        !   Spring ?
              !   Privilégier quelque chose de plus léger : Roboguice

        !   Hibernate ?
              !   Idem : Ormlite

        !   Guava ?
              !   Pourquoi pas, même si la lib est un peu lourde
                    !   Utiliser proguard pour réduire la taille du binaire final

        !   Apache Commons ?
              !   Absolument, ne réinventez pas la roue !

        !   Jackson
              !   OK, évitez de parser les json à la main 

        !   D’une manière générale
              !   Attention à la compatibilité avec le java d’Android
              !   Attention à la quantité et la taille des jars importés (dépendances transitives...)
              !   Vérifier qu’il n’y a pas un équivalent plus léger dédié à Android




42	


© OCTO 2012
Tests – Android

        !   Instrumentation Android
            !   Basé sur JUnit
            !   Test d’Activités, de Services Android, ...
                !   Manipulation du Context
            !   Exécution sur un AVD ou un device
                !   Très lent !


        !   UIAutomator
            !   Disponible à partir du SDK 16
            !   Manipulation de l’interface avec des selector (à la CSS)


        !   monkey & monkeyrunner
            !   Test du singe : événements aléatoires sur l’interface




43	


© OCTO 2012
Tests – Robotium

        !   Basé sur les tests d’instrumentation Android
               !   Aussi lent...
        !   Manipulation plus simple de l’interface
               !   Solo
        public class MaintTest extends ActivityInstrumentationTestCase2<MainActivity> {	

          private Solo solo;	

          @Override	
          protected void setUp() throws Exception {	
             super.setUp();	
             solo = new Solo(getInstrumentation(), getActivity());	
          }	

          public void testSendBob() {	
            EditText FirsteditText = (EditText) solo.getView(R.id.edittext_name);	

               solo.enterText(FirsteditText, "Bob");	
               solo.clickOnButton("Send");	

               assertTrue(solo.searchText("Hello Bob"));	
          }	



44	


© OCTO 2012
Tests – Robolectric

        !   Fonctionne sur une JVM standard
                !   Pas besoin de device ou d’émulateur pour exécuter les tests
                     !   Remplace les RuntimeException(stub) par des « Shadow Objects »
                 Beaucoup plus rapide
         @RunWith(RobolectricTestRunner.class)	
         public class MyActivityTest {	
             private Activity activity;	
             private Button pressMeButton;	
             private TextView results;	

                @Before	
                public void setUp() throws Exception {	
                    activity = new MyActivity();	
                    activity.onCreate(null);	
                    pressMeButton = (Button) activity.findViewById(R.id.press_me_button);	
                    results = (TextView) activity.findViewById(R.id.results_text_view);	
                }	

                @Test	
                public void shouldUpdateResultsWhenButtonIsClicked() throws Exception {	
                    pressMeButton.performClick();	
                    String resultsText = results.getText().toString();	
                    assertThat(resultsText, equalTo("Testing Android Rocks!"));	
                }	
         }	




45	


© OCTO 2012
Mocks

        !   Possibilité de faire du mock comme en Java

        !   Attention à Dalvik : Tous les frameworks ne sont pas compatibles
              !   Mockito
              !   Android Mock
              !   Easymock pas (encore) disponible
                  !   En cours d’adaptation


        !   Android fournit également des classes de mock pour le contexte,
            les ressources, les contentprovider, ...




46	


© OCTO 2012
Build – Ant

         !   Ant est l’outil de build initialement proposé par Google pour les
             projets Android

         !   build.xml automatiquement généré à la création d’un projet en ligne
             de commande (android create project ...)

         !   build.xml importe le build.xml fourni dans ${sdk.dir}/tools/ant/
               !   Sauf besoins supplémentaires, il n’est pas nécessaire de définir des
                   tâches de build
               !   Par défaut, couvre les besoins de compilation, packaging (release),
                   déploiements sur un device/émulateur, test, coverage (emma)

         !   Est amené à disparaître...

http://developer.android.com/tools/building/building-cmdline.html


 47	


 © OCTO 2012
Build – Maven
         !   android-maven-plugin
               <plugin>	
                 <groupId>com.jayway.maven.plugins.android.generation2</groupId>	
                 <artifactId>android-maven-plugin</artifactId>	
                 <version>3.5</version>	
               </plugin>	

               !   compile, package, test, deploie, execute, start/stop l’émulateur, obfusque,
                   release, ...

         !   android.jar sur central depuis juin 2010
               !   Ca n’a pas toujours été si simple...  : mosabua

         !   De nombreux jar de librairies également sur central
               !   Ca n’a pas toujours été si simple...  : mvn install:installl-file

         !   Intégration dans Eclipse avec m2eclipse (+ android connector)
               !   Ca n’a pas toujours été si simple...  : m2eclipse-android-plugin

         !   Intégration native dans IntelliJ 


http://code.google.com/p/maven-android-plugin/


 48	


 © OCTO 2012
Build – Gradle

         !   Gradle est le futur outil de build préconisé par Google, en
             remplacement de Ant

         !   Actuellement en version 0.1, pas stable et surtout pas
             accessible au commun des mortels (SDK previews)

         !   Un projet plus mature existe en attendant...
               !   https://github.com/jvoegele/gradle-android-plugin




http://tools.android.com/tech-docs/new-build-system/using-the-new-build-system

 49	


 © OCTO 2012
Intégration continue




              Privilégier le plugin maven au plugin jenkins pour démarrer un émulateur

50	


© OCTO 2012
Plan

   !  La plateforme Android

   !  Les bases du développement

   !  Outillage et écosystème

   !  Bonnes pratiques




51	


© OCTO 2012
Supporter la fragmentation


                   http://developer.android.com/about/dashboards	

                   29/12/2012	





              Versions du SDK	

                                      Résolutions & densités d’écrans	





52	


© OCTO 2012
Gestions des différentes versions du SDK
                         !  Oublier les versions < 2.2
                             !   3 % du parc... tanpis pour eux 

                         !  Attention quand vous développez avec
                            une version récente du SDK !
                   97%       !   Code non dispo dans les SDK antérieurs
                                  Lint saura vous le rappeler
                             !   Si besoin utiliser @TargetApi(API)!
                             !   Et vérifier la valeur de
                                 android.os.Build.VERSION.SDK_INT!

                         !  Utiliser la librairie de support
                             !   android-support.jar
                             !   Backport des fonctionnalités 3+ pour les
                                 versions >= 1.6
                                  !       Fragments
                                  !       ViewPager
                                  !       Notifications
                                  !       ...



53	


© OCTO 2012
Gestion des résolutions et densités
   !   Des dizaines de résolutions différentes
        !   320x240, 400x240, 640x240, 640x360, 480x320, 800x480, 854x480,
            800x600, 960x540, 960x640, 1280x800, 1366x768…
                                                                3 4
                                                                 	

 	

   6	

   8
   !  Densité (dp)
        !   Unité de mesure indépendante des pixels
              !   1 dp = 1 pixel en mdpi
              !   px = dp * (dpi / 160)
        !   Utiliser les dp et sp, pas les px !



   !   Oublier les small et ldpi                                                      97%
        !   3% du parc
        !   La tendance est aux grands écrans



54	


© OCTO 2012
Gestion des résolutions et densités
   !   Limiter l’utilisation de dimension fixes
           !   Privilégier wrap_content, fill_parent/match_parent
           !   Utiliser layout_weight,
                 !   Pourcentage sur l’écran
           !   Utiliser les RelativeLayout


   !   Utiliser les images xml et les 9 patch (.9.png)
           !   images extensibles
   <?xml version="1.0" encoding="utf-8"?>	
   <shape xmlns:android="http://schemas.android.com/apk/res/android" >	

        <gradient	
            android:angle="270" android:centerY="0.4"	
            android:endColor="@color/dark_blue" android:startColor="@color/blue"	
            android:centerColor="@color/light_blue" />	

        <stroke android:width="1dp" android:color="@color/border_grey" />	

        <corners android:radius="6dp" />	

        <padding android:bottom="10dp" android:left="12dp"	
            android:right="12dp" android:top="10dp" />	

   </shape>	





55	


© OCTO 2012
Gestion de la diversité
   !   Beaucoup de ressources...
        !   Il existe 18 types de qualifier : ne pas tout combiner !
        !   Ex : application Contacts Android
   ressources utiles                             traductions




56	


© OCTO 2012
Pensez aux tablettes
   !   Une tablette n’est pas nécessairement xlarge
        !   Il existe des tablettes 7’ large  utiliser sw580dp à la place


   !   Adoptez les fragments
        !   Découpage de l’UI en « Fragments »
        !   Mutualisation des layouts entre smartphone et tablette




57	


© OCTO 2012
Fragments
   !   Les fragments deviennent les contrôleurs
   !   L’activité gère la communication entre fragments
        !   transactions : ajout, suppression, remplacement de fragment

                                   !  activity.xml :
                                       <fragment 	
                                               android:name="path.to.source.Fragment" 	
                                               android:id="@+id/fragment_main_list"	
  Fragment!        Fragment.java!              android:layout_width="fill_parent"	
Activity.java
            !                                  android:layout_height="fill_parent" />	




                                   !  Fragment.java :	

                                    public View onCreateView(Inflater inflater, View container,
                                    Bundle bundle) {	
                                         return inflater.inflate(R.layout.fragment, container, false);	
                                    }	



      layout/         layout/
    activity.xml
               !    fragment.xml
                               !



58	


© OCTO 2012
User Experience – ActionBar




!   Disponible à partir du SDK 3
        !   Utiliser ActionBarSherlock
            pour les versions antérieures

!   Mixe automatique actionbar +
  menu contextuel sur les
  smartphones


59	


© OCTO 2012
User Experience – Ne bloquez pas l’UI

   !   Éviter d’instancier des objets dans les méthodes appelées des dizaines
     de fois par seconde (ex : onTouch, onScroll, onDraw...)

   !   Ne jamais faire de traitement long dans le thread UI
        !   Appels de webservices, requête complexe en bdd, decodage de bitmap, ...

   !   Utiliser des mécanismes pour faire des traitements asynchrones
        !   AsyncTask & AsyncTaskLoader
        !   Services
        !   Librairie Robospice (basée sur les services)




60	


© OCTO 2012
User Experience – Think Android !
Android


iOS


WP7


  !   Pas de bouton back
         !   Bouton physique ou dans l’ActionBar
  !   Pas d’indicateurs sur les lignes de liste
         !   Simplement rien 
  !   Les onglets (Tab) sont en haut de l’écran
  !   Les icones des applications sont différentes (pas de halo, de carré arrondi)
  !   ...



 61	


 © OCTO 2012
Ressources
   !   http://developer.android.com/index.html
        !   Site de référence : très complet

   !   http://android-developers.blogspot.fr/
        !   Blog officiel Google Android : annonces et bons articles

   !   http://www.androiduipatterns.com/
        !   Blog sur les patterns UI et UX

   !   http://androiddevweekly.com/
        !   Toutes les semaines, des articles, des libs, des exemples, des tutos...

   !  http://android.cyrilmottier.com/
        !   Blog de Cyril Mottier, un expert Android reconnu

   !   Twitter : #android #androiddev
   !   Google+ : +AndroidDevelopers



62	


© OCTO 2012
Questions




63	


© OCTO 2012

Jug Lausanne Android Janvier2013

  • 1.
    Android JUG Lausanne Janvier 2013 Jérôme Van Der Linden 1 © OCTO 2012
  • 2.
    Moi !   Architecte Java/JEE @ Octo !   Archi, dev, audit, conseil Metroide !   jva@octo.com !   Développeur Android depuis 2009 Android !   Metroide Holo !   Formateur Octo depuis 2010 Colors !   Auteur de android-holo-colors.com !   Co-Inventeur de Appaloosa !   Co-Auteur de Robospice @jeromevdl +Jérôme Van Der Linden 2 © OCTO 2012
  • 3.
    Plan !  La plateforme Android !  Les bases du développement !  Outillage et écosystème !  Bonnes pratiques 3 © OCTO 2012
  • 4.
    Plan !  La plateforme Android !  Les bases du développement !  Outillage et écosystème !  Bonnes pratiques 4 © OCTO 2012
  • 5.
    08/2005 11/2007 08/200810/2008 05/2009 09/2009 01/2010 Rachat SDK 1.0 SDK 1.5 1er SDK Startup OHA Market (utilisable) SDK 1.6 SDK 2.1 public v0.9 Android HTC G1 HTC G2 05/2010 12/2010 02/2011 10/2011 02/2012 07/2012 SDK 3.0 Market SDK 2.2 Push SDK 2.3 Tablettes SDK 4.0 devient SDK 4.1 ... only PlayStore 5 © OCTO 2012
  • 6.
    Quelques chiffres nombre d'applications sur Google Play Store 6 © OCTO 2012
  • 7.
  • 8.
    Java !   Sous ensemble de l’implémentation Apache Harmony !   JavaSE 5 !   Et aussi ... !   Junit (3.8) !   Apache commons logging et HttpComponents !   Parsers json et xml !   Mais ... !   Toutes les méthodes des classe Android sont stubés !   throw new RuntimeException("Stub"); !   Impossible d’exécuter / tester sans émulateur / device 8 © OCTO 2012
  • 9.
    DVM : DalvikVirtual Machine code bytecode application .java .class .dex .apk javac dx apkbuilber !   Compilation JIT depuis Android 2.2 !   Pas de génération de bytcode au runtime !  runtime weaving KO !  mais compiletime OK !   Des tentatives de groovy, scala !   GC mark&sweep https://sites.google.com/site/io/dalvik-vm-internals 9 © OCTO 2012
  • 10.
    Sécurité !   Système basé sur Linux !   users, groups, droits... : par défaut l’utilisateur n’est pas root !   Sandboxing !   Une VM par application !   Un user unique par application !   Un process unique par application !   Un espace dédié du filesystem par application !   Permissions !   Un ensemble de permissions pour accéder aux différents services !   Les permissions sont affichées avant l’installation de l’application !   Signature !   Les applications sont signées pour être publiées sur le store !   Communications !   Les applications ne peuvent communiquer entre elles sauf !   Par des Intents !   Si elles utilisent un filesystem commun (ex: SDCard) !   Si elles autorisent explicitement dans le manifest (ContentProviders, Services !   Si elles ont la même signature (partage du même user id) 10 © OCTO 2012
  • 11.
    Plan !  La plateforme Android !  Les bases du développement !  Outillage et écosystème !  Bonnes pratiques 11 © OCTO 2012
  • 12.
    Structure d’un projet Classes java Classes de mapping des ressources Android JAR d’Android Ressources « brutes » Ressources mappées par Android : - images (png, xml) -  animation (xml) -  écrans (xml) -  menus (xml) -  media (wav, aac, mp3, H.264, mpeg4, ogg) -  data : textes, styles couleurs, tableaux… (xml) Manifest de l’application 12 © OCTO 2012
  • 13.
    AndroidManifest.xml <manifest xmlns:android="http://schemas.android.com/apk/res/android" Identification package="com.octo.android.askbob" android:versionCode="1" formelle de android:versionName="1.0" > l’application <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="16" /> <uses-feature android:name="android.hardware.bluetooth" /> Contraintes tech de l’application <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> Permissions de <application l’application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".activity.SplashScreenActivity" android:theme="@android:style/Theme.NoTitleBar" > Contenu de <intent-filter> l’application : <action android:name="android.intent.action.MAIN" /> Icône, Nom, <category android:name="android.intent.category.LAUNCHER" /> Activités, Services </intent-filter> </activity> <activity android:name=".activity.OctoDetailActivity" /> <service android:name="com.octo.android.askbob.network.AskBobJsonSpiceService" android:exported="false" /> </application> </manifest> 13 © OCTO 2012
  • 14.
    Permissions !   130 permissions !   internet, gps, bluetooth, contacts, telephone, sms, camera, vibreur, état du réseau/wifi, accès a la SD... 14 © OCTO 2012
  • 15.
    Ressources public final class R { public static final class drawable { public static final int ic_dictionary=0x7f020000; public static final int ic_menu_search=0x7f020001; } public static final class layout { public static final int main=0x7f030000; public static final int result=0x7f030001; public static final int word=0x7f030002; } public static final class menu { public static final int options_menu=0x7f080000; } public static final class string { /** The name of the application. */ public static final int app_name=0x7f060000; /** The menu entry that invokes search. */ public static final int menu_search=0x7f060003; } public static final class id { public static final int list=0x7f090001; public static final int text=0x7f090000; } //... } R.java strings.xml <TextView main.xml <resources> android:id="@+id/text" <!-- The name of the application. --> android:layout_width="fill_parent" <string name="app_name">Dictionary</string> android:layout_height="wrap_content" /> <ListView <!-- The menu entry that invokes search. --> android:id="@+id/list" <string name="menu_search">Search</string> android:layout_width="fill_parent" </resources> android:layout_height="0dp"> 15 © OCTO 2012
  • 16.
    Utilisation des ressources public final class R { public static final class drawable { public static final int ic_dictionary=0x7f020000; public static final int ic_menu_search=0x7f020001; } public static final class layout { public static final int main=0x7f030000; !   Utilisable dans le code java public static final int result=0x7f030001; public static final int word=0x7f030002; !   getResources.getDrawable } public static final class menu { (R.drawable.ic_menu_search) public static final int options_menu=0x7f080000; } !   getResources.getString public static final class string { /** The name of the application. (R.string.menu_search) */ public static final int app_name=0x7f060000; /** The menu entry that invokes search. */ !   Et dans les xml } public static final int menu_search=0x7f060003; public static final class id { !   @drawable/ic_dictionnary public static final int list=0x7f090001; public static final int text=0x7f090000; !   @string/menu_search } //... !   @id/text } R.java 16 © OCTO 2012
  • 17.
    Layout !   Définit la structure visuelle de l’IHM, conteneur d’éléments graphiques !   Généralement défini en XML à la XUL <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <Button android:id="@+id/button" android:text="@string/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> !   Et récupérable depuis Java : Button button = (Button) findViewById(R.id.button); !   Ou instancié dynamiquement en java à la Swing !   Plus rare sauf pour vos propres composants SuperExtendedButton button = new SuperExtendedButton(context); button.setText(R.string.button1); layout.addView(button); 17 © OCTO 2012
  • 18.
    MVC Contrôleur Activity, Fragment Modèle Vue POJO, DB Layout (XML) 18 © OCTO 2012
  • 19.
    MVC public class DetailActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_detail); TextView fullNameTextView = (TextView) findViewById(R.id.detail_fullname); } } activity_detail.xml DetailActivity.java <?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/detail_background" > <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" Contrôleur android:padding="5dp" > <TextView Activity, android:id="@+id/detail_fullname" style="@style/DetailTitle" android:layout_width="wrap_content" Fragment android:layout_height="wrap_content"/> <Button style="@style/DetailButton" Modèle Vue android:id="@+id/detail_mobile_button" android:layout_below="@id/detail_fullname" android:drawableLeft="@drawable/ic_menu_call" /> </RelativeLayout> POJO, DB Layout (XML) </ScrollView> 19 © OCTO 2012
  • 20.
    Cycle de viedes activités !   onSaveInstanceState : !   backup des donnés de l’écran lors d’un changement de configuration (rotation de l’écran, reception d’un appel, ...) 20 © OCTO 2012
  • 21.
    Intents – Navigationentre Activités !   Résolution explicite !   Spécification d’un composant (class) Intent intent = new Intent(ActivityA.this, ActivityB.class); ActivityA startActivity(intent); ActivityB // OU startActivityForResult(intent, REQUEST_CODE); !   Passage de paramètres !   Types primitifs (boolean, int, double, ...) + String !   Serializable !   Parcelable intent.putExtra(String key, value); !   Réception des paramètres protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ActivityB getIntent().getStringExtra(key); getIntent().getParcelableExtra(key2); // ... } 21 © OCTO 2012
  • 22.
    Parcelable public class User implements Parcelable { private String name; private int age; public int describeContents() { return 0; } public void writeToParcel(Parcel dest, int flags) { dest.writeString(name); dest.writeInt(age); } public User(Parcel userParcel) { name = userParcel.readString(); age = userParcel.readInt(); } public static final Parcelable.Creator<User> CREATOR = new Parcelable.Creator<User>() { public User createFromParcel(Parcel in) { return new User(in); } public User[] newArray(int size) { return new User[size]; } }; } 22 © OCTO 2012
  • 23.
    Intents – Navigationdans le système !   Résolution implicite !   Via une action !   Exemple: partager du contenu Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND); sharingIntent.setType("text/plain"); sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Subject Here"); sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, "Content to share"); startActivity(Intent.createChooser(sharingIntent, "Share via")); !   Rendre son application réceptive à un Intent !   Via les intent-filter : action + category + data <activity android:name="ShareActivity" > <intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> <data android:mimeType="image/*" /> </intent-filter> </activity> 23 © OCTO 2012
  • 24.
    Événements !   onClick !   Disponible depuis le SDK 1.6, auparavant, il fallait définir un OnClickListener... <Button layout activity android:id="@+id/button" public void onButtonClick(View v) { android:layout_width="wrap_content" // do something android:layout_height="wrap_content" } android:onClick="onButtonClick" /> !   Listeners !   OnClickListener textview.setOnKeyListener(new OnKeyListener() { !   OnFocusChangeListener @Override public boolean onKey(View v, int keyCode, KeyEvent event) !   OnKeyListener { // do something !   OnDragListener return false; } !   OnCheckedChangeListener }); !   OnMenuItemClickListener !   OnItemSelectedListener !   ... 24 © OCTO 2012
  • 25.
    LinearLayout !   Alignement Horizontal ou Vertical <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/ apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button1" /> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button1" /> <Button android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button1" /> </LinearLayout> 25 © OCTO 2012
  • 26.
    RelativeLayout !   Positionnement relatif <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http:// schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <Button android:id="@+id/button1" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/button1" /> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/button1" android:layout_alignLeft="@id/button1" android:text="@string/button2" /> <Button android:id="@+id/button3" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_toRightOf="@id/button2" android:layout_below="@id/button1" android:text="@string/button3" /> </RelativeLayout> 26 © OCTO 2012
  • 27.
    TableLayout <?xml version="1.0" encoding="utf-8"?> <TableLayout xmlns:android="http:// schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <TableRow> <Button android:id="@+id/button1" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/button1" /> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button2" /> </TableRow> <TableRow> <Button android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button3" /> <Button android:id="@+id/button4" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/button3" /> </TableRow> </TableLayout> 27 © OCTO 2012
  • 28.
    Conteneurs (!= layout) ListView TabView MapView WebView GridView ScrollView 28 © OCTO 2012
  • 29.
    Listes !   Listview <ListView android:id="@android:id/list" android:layout_width="fill_parent" android:layout_height="fill_parent" /> !   Utilisation d’Adapters pour populer la liste !   Idem pour les Gridview !   listview.setAdapter(myAdapter); !   BaseAdapter, ArrayAdapter, CursorAdapter public class MyAdapter extends BaseAdapter { public int getCount() {} // return cell number public Object getItem(int position) {} // return model object for the cell public long getItemId(int position) {} // return cell object id (position) public View getView(int position, View convertView, ViewGroup parent) { View cell = null; if (convertView == null) { // create view by inflating layout for the cell here } else { cell = convertView; // recycle an older cell } // set cell attributes here return cell; } } 29 © OCTO 2012
  • 30.
    Composants graphiques Checkbox Button ProgressBar Radio Switch Spinner SeekBar Picker Dialog 30 © OCTO 2012
  • 31.
    Adoptez votre proprestyle !   Soit le champ texte suivant : <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" android:textColor="#00FF00" android:typeface="monospace" /> !   On peut extraire le style suivant : <resources> <style name="CodeFont" parent="@android:style/TextAppearance.Medium"> <item name="android:layout_width">fill_parent</item> <item name="android:layout_height">wrap_content</item> <item name="android:textColor">#00FF00</item> <item name="android:typeface">monospace</item> </style> </resources> !   Et réduire ainsi le champ texte à : <TextView style="@style/CodeFont" android:text="@string/hello" /> !   Mais surtout le rendre disponible à d’autres champs textes sans dupliquer des lignes et des lignes de propriétés 31 © OCTO 2012
  • 32.
    Héritage des styles !   Héritage d’un style système <style name="GreenText" parent="@android:style/TextAppearance"> <item name="android:textColor">#00FF00</item> </style> !   Héritage d’un style défini <style name="CodeFont.Red"> <item name="android:textColor">#FF0000</item> </style> <style name="CodeFont.Red.Big"> <item name="android:textSize">30dp</item> </style> !   Surcharge <style name="CodeFont.Red.Dark"> <item name="android:textColor">#FF6611</item> </style> 32 © OCTO 2012
  • 33.
    Theme = ∑styles !   Un thème est un ensemble de styles appliqués à toute l’application ou à une activité entière !   Définition dans le fichier AndroidManifest.xml <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@android:style/Theme.Holo.Light" > <activity android:name=".activity.SplashScreenActivity" android:theme="@android:style/Theme.NoTitleBar" /> !   Depuis Honeycomb, Thème Holo (inspiré du film Tron) !   basé sur la couleur bleu #33b5e5 !   Pensez à étendre le style Holo ou Holo.Light pour vos thèmes <style name="CustomTheme" parent="android:Theme.Holo.Light"> <item name="android:windowBackground">@color/custom_theme_color</item> <item name="android:colorBackground">@color/custom_theme_color</item> </style> 33 © OCTO 2012
  • 34.
    Plan !  La plateforme Android !  Les bases du développement !  Outillage et écosystème !  Bonnes pratiques 34 © OCTO 2012
  • 35.
    Développement !   SDK Android !   Windows / Mac / Linux !   SDK Manager (« android ») !   Tools !   Platform-tools !   Sources 35 © OCTO 2012
  • 36.
    Eclipse + ADT !   Android Developer Tools (ADT) !   Création, compilation, debug, packaging !   Auto complétion dans le XML !   Editeur WYSIWYG !   DDMS, analyse des devices : !   thread, !   mémoire, !   filesystem, !   simulation d’appels, de SMS, de GPS, ... !   Logcat !   accès aux logs des devices 36 © OCTO 2012
  • 37.
    IntelliJ !   Support natif d’Android !   Même fonctionnalités que ADT !   Éditeur WYSIWYG depuis la v12 : 37 © OCTO 2012
  • 38.
    SDK Tools !   android !   Permet de télécharger les différentes versions du SDK (SDK Manager) !   Permet de créer des projets Android !   Permet de créer des images AVD (Android Virtual Device) !   emulator !   Emule les images AVD !   Permet de tester/debugger l’application !   adb (Android Debug Bridge) !   Permet d’installer des apk (Android PacKage) sur le device !   Permet de copier des fichiers sur le device !   Permet d’exécuter des commandes shell sur le device 38 © OCTO 2012
  • 39.
    SDK Tools !   Lint !   Analyse du code Android (~ PMD/Findbugs Android) !   Intégré à Eclipse et IntelliJ !   hierarchyviewer !   Permet de visualiser l’arbre des vues pour optimiser les perfs de l’UI !   draw9patch !   Permet de créer des png « extensibles » !   Fichier « .9.png » !   traceview !   Profiling d’une application en cours d’exécution 39 © OCTO 2012
  • 40.
    Librairies !   Roboguice: Google guice pour Android !   Injection de dépendances !   Injection de view... !   Spring Android !   RestTemplate pour faciliter les appels de services HTTP/REST !   Robospice !   Traitements réseaux asynchrones !   Mise en cache !   Ormlite !   ORM léger pour Sqlite 40 © OCTO 2012
  • 41.
    Librairies !   ActionBarSherlock !   Mise à disposition des ActionBar sur les Android < 3.0 !   HoloEverywhere !   Mise à disposition du thème Holo pour les Android < 3.0 !   Android Asset Studio & Android Holo Colors !   Création d’icônes, d’images (holo), de fichiers de styles, ... !   Et des dizaines d’autres disponibles sur !   http://www.theultimateandroidlibrary.com/ !   http://www.openintents.org/en/libraries !   http://www.androidviews.net/ 41 © OCTO 2012
  • 42.
    Et mes librairiesJava ? !   Spring ? !   Privilégier quelque chose de plus léger : Roboguice !   Hibernate ? !   Idem : Ormlite !   Guava ? !   Pourquoi pas, même si la lib est un peu lourde !   Utiliser proguard pour réduire la taille du binaire final !   Apache Commons ? !   Absolument, ne réinventez pas la roue ! !   Jackson !   OK, évitez de parser les json à la main  !   D’une manière générale !   Attention à la compatibilité avec le java d’Android !   Attention à la quantité et la taille des jars importés (dépendances transitives...) !   Vérifier qu’il n’y a pas un équivalent plus léger dédié à Android 42 © OCTO 2012
  • 43.
    Tests – Android !   Instrumentation Android !   Basé sur JUnit !   Test d’Activités, de Services Android, ... !   Manipulation du Context !   Exécution sur un AVD ou un device !   Très lent ! !   UIAutomator !   Disponible à partir du SDK 16 !   Manipulation de l’interface avec des selector (à la CSS) !   monkey & monkeyrunner !   Test du singe : événements aléatoires sur l’interface 43 © OCTO 2012
  • 44.
    Tests – Robotium !   Basé sur les tests d’instrumentation Android !   Aussi lent... !   Manipulation plus simple de l’interface !   Solo public class MaintTest extends ActivityInstrumentationTestCase2<MainActivity> { private Solo solo; @Override protected void setUp() throws Exception { super.setUp(); solo = new Solo(getInstrumentation(), getActivity()); } public void testSendBob() { EditText FirsteditText = (EditText) solo.getView(R.id.edittext_name); solo.enterText(FirsteditText, "Bob"); solo.clickOnButton("Send"); assertTrue(solo.searchText("Hello Bob")); } 44 © OCTO 2012
  • 45.
    Tests – Robolectric !   Fonctionne sur une JVM standard !   Pas besoin de device ou d’émulateur pour exécuter les tests !   Remplace les RuntimeException(stub) par des « Shadow Objects »  Beaucoup plus rapide @RunWith(RobolectricTestRunner.class) public class MyActivityTest { private Activity activity; private Button pressMeButton; private TextView results; @Before public void setUp() throws Exception { activity = new MyActivity(); activity.onCreate(null); pressMeButton = (Button) activity.findViewById(R.id.press_me_button); results = (TextView) activity.findViewById(R.id.results_text_view); } @Test public void shouldUpdateResultsWhenButtonIsClicked() throws Exception { pressMeButton.performClick(); String resultsText = results.getText().toString(); assertThat(resultsText, equalTo("Testing Android Rocks!")); } } 45 © OCTO 2012
  • 46.
    Mocks !   Possibilité de faire du mock comme en Java !   Attention à Dalvik : Tous les frameworks ne sont pas compatibles !   Mockito !   Android Mock !   Easymock pas (encore) disponible !   En cours d’adaptation !   Android fournit également des classes de mock pour le contexte, les ressources, les contentprovider, ... 46 © OCTO 2012
  • 47.
    Build – Ant !   Ant est l’outil de build initialement proposé par Google pour les projets Android !   build.xml automatiquement généré à la création d’un projet en ligne de commande (android create project ...) !   build.xml importe le build.xml fourni dans ${sdk.dir}/tools/ant/ !   Sauf besoins supplémentaires, il n’est pas nécessaire de définir des tâches de build !   Par défaut, couvre les besoins de compilation, packaging (release), déploiements sur un device/émulateur, test, coverage (emma) !   Est amené à disparaître... http://developer.android.com/tools/building/building-cmdline.html 47 © OCTO 2012
  • 48.
    Build – Maven !   android-maven-plugin <plugin> <groupId>com.jayway.maven.plugins.android.generation2</groupId> <artifactId>android-maven-plugin</artifactId> <version>3.5</version> </plugin> !   compile, package, test, deploie, execute, start/stop l’émulateur, obfusque, release, ... !   android.jar sur central depuis juin 2010 !   Ca n’a pas toujours été si simple...  : mosabua !   De nombreux jar de librairies également sur central !   Ca n’a pas toujours été si simple...  : mvn install:installl-file !   Intégration dans Eclipse avec m2eclipse (+ android connector) !   Ca n’a pas toujours été si simple...  : m2eclipse-android-plugin !   Intégration native dans IntelliJ  http://code.google.com/p/maven-android-plugin/ 48 © OCTO 2012
  • 49.
    Build – Gradle !   Gradle est le futur outil de build préconisé par Google, en remplacement de Ant !   Actuellement en version 0.1, pas stable et surtout pas accessible au commun des mortels (SDK previews) !   Un projet plus mature existe en attendant... !   https://github.com/jvoegele/gradle-android-plugin http://tools.android.com/tech-docs/new-build-system/using-the-new-build-system 49 © OCTO 2012
  • 50.
    Intégration continue Privilégier le plugin maven au plugin jenkins pour démarrer un émulateur 50 © OCTO 2012
  • 51.
    Plan !  La plateforme Android !  Les bases du développement !  Outillage et écosystème !  Bonnes pratiques 51 © OCTO 2012
  • 52.
    Supporter la fragmentation http://developer.android.com/about/dashboards 29/12/2012 Versions du SDK Résolutions & densités d’écrans 52 © OCTO 2012
  • 53.
    Gestions des différentesversions du SDK !  Oublier les versions < 2.2 !   3 % du parc... tanpis pour eux  !  Attention quand vous développez avec une version récente du SDK ! 97% !   Code non dispo dans les SDK antérieurs  Lint saura vous le rappeler !   Si besoin utiliser @TargetApi(API)! !   Et vérifier la valeur de android.os.Build.VERSION.SDK_INT! !  Utiliser la librairie de support !   android-support.jar !   Backport des fonctionnalités 3+ pour les versions >= 1.6 !   Fragments !   ViewPager !   Notifications !   ... 53 © OCTO 2012
  • 54.
    Gestion des résolutionset densités !   Des dizaines de résolutions différentes !   320x240, 400x240, 640x240, 640x360, 480x320, 800x480, 854x480, 800x600, 960x540, 960x640, 1280x800, 1366x768… 3 4 6 8 !  Densité (dp) !   Unité de mesure indépendante des pixels !   1 dp = 1 pixel en mdpi !   px = dp * (dpi / 160) !   Utiliser les dp et sp, pas les px ! !   Oublier les small et ldpi 97% !   3% du parc !   La tendance est aux grands écrans 54 © OCTO 2012
  • 55.
    Gestion des résolutionset densités !   Limiter l’utilisation de dimension fixes !   Privilégier wrap_content, fill_parent/match_parent !   Utiliser layout_weight, !   Pourcentage sur l’écran !   Utiliser les RelativeLayout !   Utiliser les images xml et les 9 patch (.9.png) !   images extensibles <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" > <gradient android:angle="270" android:centerY="0.4" android:endColor="@color/dark_blue" android:startColor="@color/blue" android:centerColor="@color/light_blue" /> <stroke android:width="1dp" android:color="@color/border_grey" /> <corners android:radius="6dp" /> <padding android:bottom="10dp" android:left="12dp" android:right="12dp" android:top="10dp" /> </shape> 55 © OCTO 2012
  • 56.
    Gestion de ladiversité !   Beaucoup de ressources... !   Il existe 18 types de qualifier : ne pas tout combiner ! !   Ex : application Contacts Android ressources utiles traductions 56 © OCTO 2012
  • 57.
    Pensez aux tablettes !   Une tablette n’est pas nécessairement xlarge !   Il existe des tablettes 7’ large  utiliser sw580dp à la place !   Adoptez les fragments !   Découpage de l’UI en « Fragments » !   Mutualisation des layouts entre smartphone et tablette 57 © OCTO 2012
  • 58.
    Fragments !   Les fragments deviennent les contrôleurs !   L’activité gère la communication entre fragments !   transactions : ajout, suppression, remplacement de fragment !  activity.xml : <fragment android:name="path.to.source.Fragment" android:id="@+id/fragment_main_list" Fragment! Fragment.java! android:layout_width="fill_parent" Activity.java ! android:layout_height="fill_parent" /> !  Fragment.java : public View onCreateView(Inflater inflater, View container, Bundle bundle) { return inflater.inflate(R.layout.fragment, container, false); } layout/ layout/ activity.xml ! fragment.xml ! 58 © OCTO 2012
  • 59.
    User Experience –ActionBar !   Disponible à partir du SDK 3 !   Utiliser ActionBarSherlock pour les versions antérieures !   Mixe automatique actionbar + menu contextuel sur les smartphones 59 © OCTO 2012
  • 60.
    User Experience –Ne bloquez pas l’UI !   Éviter d’instancier des objets dans les méthodes appelées des dizaines de fois par seconde (ex : onTouch, onScroll, onDraw...) !   Ne jamais faire de traitement long dans le thread UI !   Appels de webservices, requête complexe en bdd, decodage de bitmap, ... !   Utiliser des mécanismes pour faire des traitements asynchrones !   AsyncTask & AsyncTaskLoader !   Services !   Librairie Robospice (basée sur les services) 60 © OCTO 2012
  • 61.
    User Experience –Think Android ! Android iOS WP7 !   Pas de bouton back !   Bouton physique ou dans l’ActionBar !   Pas d’indicateurs sur les lignes de liste !   Simplement rien  !   Les onglets (Tab) sont en haut de l’écran !   Les icones des applications sont différentes (pas de halo, de carré arrondi) !   ... 61 © OCTO 2012
  • 62.
    Ressources !   http://developer.android.com/index.html !   Site de référence : très complet !   http://android-developers.blogspot.fr/ !   Blog officiel Google Android : annonces et bons articles !   http://www.androiduipatterns.com/ !   Blog sur les patterns UI et UX !   http://androiddevweekly.com/ !   Toutes les semaines, des articles, des libs, des exemples, des tutos... !  http://android.cyrilmottier.com/ !   Blog de Cyril Mottier, un expert Android reconnu !   Twitter : #android #androiddev !   Google+ : +AndroidDevelopers 62 © OCTO 2012
  • 63.