Contenu connexe Similaire à Jug Lausanne Android Janvier2013 (20) Jug Lausanne Android Janvier20131. 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/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
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 : 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
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 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
21. 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
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 – 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
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
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 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
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 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
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é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
54. 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
55. 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
56. 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
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