Android Optimisations Greendroid
-
Upload
gdg-nantes -
Category
Technology
-
view
3.742 -
download
0
Transcript of Android Optimisations Greendroid
![Page 1: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/1.jpg)
http://www.cyrilmottier.com@cyrilmottier
Cyril Mottier
Optimisations généralessous Android et GreenDroid
Concevoir des applications réactives, fluides et facile d’utilisation
![Page 2: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/2.jpg)
Note généraleMais qui est donc ce personnage ?
![Page 3: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/3.jpg)
Moi - 1/2
![Page 4: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/4.jpg)
Moi - 1/2
• Bloggueur• http://android.cyrilmottier.com
![Page 5: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/5.jpg)
Moi - 1/2
• Bloggueur• http://android.cyrilmottier.com
• Développeur• MetroMap Paris• GreenDroid
![Page 6: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/6.jpg)
Moi - 1/2
• Bloggueur• http://android.cyrilmottier.com
• Développeur• MetroMap Paris• GreenDroid
• Adorateur et prêcheur d’Android• Droidcon UK, ADL Paris, GET, PAUG, etc.
![Page 7: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/7.jpg)
Moi - 2/2
• Auteur• Développez sur Android
chez Digit Books• Co-écrit avec Ludovic Perrier
http://j.mp/hCIJzj
![Page 8: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/8.jpg)
IntroductionPrésentation des contraintes
![Page 9: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/9.jpg)
Sous nos pieds ... - 1/3
• Système adapté aux terminaux contraints• Peu de puissance• Peu de mémoire• Peu de batterie• Peu d’espace d’affichage
![Page 10: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/10.jpg)
Sous nos pieds ... - 2/3
• Machine Virtuelle basique• La fameuse Dalvik VM• Pas de JIT (avant Froyo)
![Page 11: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/11.jpg)
Sous nos pieds ... - 3/3
• Ramasse-miettes (garbage collector - GC) basique• Mark and sweep
• stop-the-world (pré Gingerbread)• Concurrent (post Gingerbread)
![Page 12: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/12.jpg)
Le ramasse-miettes - 1/2
![Page 13: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/13.jpg)
Le ramasse-miettes - 1/2
![Page 14: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/14.jpg)
Le ramasse-miettes - 2/2
![Page 15: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/15.jpg)
Le ramasse-miettes - 2/2
![Page 16: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/16.jpg)
Android aurait-il unproblème de
performance ?
Conclusion - 1/2
![Page 17: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/17.jpg)
Android aurait-il unproblème de
performance ?NON
Conclusion - 1/2
![Page 18: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/18.jpg)
Conclusion - 2/2
![Page 19: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/19.jpg)
Conclusion - 2/2
• GC non contrôlable• Oubliez System.gc() !• Voyez le GC comme une entité indépendante
![Page 20: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/20.jpg)
Conclusion - 2/2
• GC non contrôlable• Oubliez System.gc() !• Voyez le GC comme une entité indépendante
• Pensez différemment ...• Utilisez les types primitifs• Minimisez la création d’objets• Réutilisez les objets
![Page 21: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/21.jpg)
Conclusion - 2/2
• GC non contrôlable• Oubliez System.gc() !• Voyez le GC comme une entité indépendante
• Pensez différemment ...• Utilisez les types primitifs• Minimisez la création d’objets• Réutilisez les objets
Si nécessaire !
![Page 22: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/22.jpg)
Optimisations JavaEtude du langage, de ses facilités et
de ses inconvénients
![Page 23: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/23.jpg)
• Introduit en 1996• Langage haut-niveau
• Langage objet fortement typé• Pas/peu de gestion mémoire• Syntaxe avancée (foreach, etc.)
• Apparente simplicité• Cache des points d’ombre
Le langage Java
![Page 24: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/24.jpg)
Autoboxing
public int factBad(int arg) { if (arg < 0) { throw new ArithmeticException("arg must be a positive integer"); } Integer result = 1; for (int i = 2; i <= arg; i++) { result *= i; } return result;}
![Page 25: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/25.jpg)
Autoboxing
public int factBad(int arg) { if (arg < 0) { throw new ArithmeticException("arg must be a positive integer"); } Integer result = 1; for (int i = 2; i <= arg; i++) { result *= i; } return result;}
public int factBad2(int arg) { if (arg < 0) { throw new ArithmeticException("arg must be a positive integer"); } Integer result = new Integer(1); for (int i = 2; i <= arg; i++) { result = new Integer(result.intValue() * i); } return result.intValue();}
équivaut à
![Page 26: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/26.jpg)
• Utilisez les types primitifs• byte, short, int, long• float, double• boolean, char
Autoboxing
public int factGood2(int arg) { if (arg < 0) { throw new ArithmeticException(); } return (arg == 0) ? 1 : arg * factGood2(arg - 1);}
public int factGood(int arg) { if (arg < 0) { throw new ArithmeticException(); } int result = 1; for (int i = 2; i <= arg; i++) { result *= i; } return result;}
![Page 27: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/27.jpg)
Les types génériques
HashMap<Integer, String> hashMap = new HashMap<Integer, String>();hashMap.put(664, "PAUG");hashMap.put(665, "is");hashMap.put(666, "awesome");
// ...hashMap.get(666);// ...
![Page 28: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/28.jpg)
Les types génériques
HashMap<Integer, String> hashMap = new HashMap<Integer, String>();hashMap.put(664, "PAUG");hashMap.put(665, "is");hashMap.put(666, "awesome");
// ...hashMap.get(666);// ...
HashMap<Integer, String> hashMap = new HashMap<Integer, String>();hashMap.put(new Integer(664), "PAUG");hashMap.put(new Integer(665), "is");hashMap.put(new Integer(666), "awesome");
// ...hashMap.get(new Integer(666));// ...
équivaut à
![Page 29: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/29.jpg)
• Préférez les SparseArrays (android.util) :• SparseBooleanArray• SparseIntArray• SparseArray• LongSparseArray (API privée)
Les types génériques
SparseArray<String> sparseArray = new SparseArray<String>();sparseArray.put(664, "PAUG");sparseArray.put(665, "is");sparseArray.put(666, "awesome");
// ...sparseArray.get(666);// ...
![Page 30: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/30.jpg)
Temporaires contre statiques - 1/2
public boolean intersect(int left, int top, int right, int bottom) { return intersect(new Rect(left, top, right, bottom));}
public abstract boolean intersect(Rect rect);
![Page 31: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/31.jpg)
Temporaires contre statiques - 1/2
public boolean intersect(int left, int top, int right, int bottom) { return intersect(new Rect(left, top, right, bottom));}
public abstract boolean intersect(Rect rect);
private static final Rect sRect = new Rect();
public boolean intersect(int left, int top, int right, int bottom) { sRect.set(left, top, right, bottom); return intersect(sRect);}
public abstract boolean intersect(Rect rect);
Préférez les statiques aux temporaires ...
![Page 32: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/32.jpg)
Temporaires contre statiques - 2/2
• Technique dédiée aux méthodes critiques• onDraw(), onMeasure(), onLayout(), getView(), etc.
• Paint• Rect• Point
• Classes utilitaires• Random
• Méthodes à retour via arguments• Location.distanceBetween( ..., float[] results)
![Page 33: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/33.jpg)
Les arguments variables
public void main() { varargs(1, 2, 3);}
public abstract void varargs(int ... args);
![Page 34: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/34.jpg)
Les arguments variables
public void main() { varargs(1, 2, 3);}
public abstract void varargs(int ... args);
public void main() { varargs(new int[]{1, 2, 3});}
public abstract void varargs(int ... args);
est équivalent à la création d’un tableau ...
![Page 35: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/35.jpg)
Les itérateurs - 1/2
public void iteratorBad(List<T> list) {
for (T obj : list) { // ... }}
![Page 36: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/36.jpg)
Les itérateurs - 1/2
public void iteratorBad(List<T> list) {
for (T obj : list) { // ... }}
public void iteratorBad(List<T> list) {
T obj; for (Iterator<T> i = list.iterator(); i.hasNext(); obj = i.next()) { // ... }}
Revient à créer un Iterator
![Page 37: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/37.jpg)
• Utilisez la syntaxe foreach :• Facile à lire• Optimisée
• Limitez la casse !
Les itérateurs - 2/2
public void iteratorGood(List<T> list) { if (list != null && list.size() != 0) { for (T obj : list) { // ... } }}
![Page 38: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/38.jpg)
Les Strings - 1/3
private static final String SLOGAN = "This" + " " + "conference" + " " + "is" + " " + "awesome";
public String getSlogan() { return SLOGAN;}
![Page 39: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/39.jpg)
Les Strings - 1/3
private static final String SLOGAN = "This" + " " + "conference" + " " + "is" + " " + "awesome";
public String getSlogan() { return SLOGAN;}
private static final String SLOGAN = "This conference is awesome";
public String getSlogan() { return "This conference is awesome";}
est résolu à la compilation par
![Page 40: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/40.jpg)
Les Strings - 2/3
public String concatBad(String[] strings) { String result = null;
for (String s : strings) { result += s; } return result;}
![Page 41: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/41.jpg)
Les Strings - 2/3
public String concatBad(String[] strings) { String result = null;
for (String s : strings) { result += s; } return result;}
public String concatBad(String[] strings) { String result = null;
for (String s : strings) { result = new StringBuilder(result).append(s).toString(); } return result;}
entraine l’instanciation d’un StringBuilder
![Page 42: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/42.jpg)
Les Strings - 3/3
public String concatCorrect(String[] strings) { StringBuilder result = new StringBuilder();
for (String s : strings) { result.append(s); } return result.toString();}
![Page 43: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/43.jpg)
Les Strings - 3/3
public String concatCorrect(String[] strings) { StringBuilder result = new StringBuilder();
for (String s : strings) { result.append(s); } return result.toString();}
private static StringBuilder sStringBuilder = new StringBuilder();
public String concatGood(String[] strings) { sStringBuilder.setLength(0); for (String s : strings) { sStringBuilder.append(s); } return sStringBuilder.toString();}
Ou encore mieux ...
![Page 44: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/44.jpg)
Quelques astuces
• Réutilisez les objets• ViewHolder et convertView avec les ListViews/Adapters• Handler.obtainMessage() / Message.obtain()• Classes dans android.util :
• PoolableManager, Pool, Poolable, Pools, FinitePool, SynchronizedPool
• Evitez la création d’objets• CharArrayBuffer avec les Cursors• SparseArray
![Page 45: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/45.jpg)
Optimisations UIMettez de la puissance et de la fluidité
à vos interfaces graphiques !
![Page 46: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/46.jpg)
Layouts optimisésDéveloppeurs et bûcherons : même combat !
![Page 47: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/47.jpg)
Présentation
![Page 48: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/48.jpg)
Présentation
• Un maître mot : MINIMISATION !
![Page 49: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/49.jpg)
Présentation
• Un maître mot : MINIMISATION !• Moins de vues équivaut à :
• measure() plus rapide• layout() plus rapide• draw() plus rapide
![Page 50: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/50.jpg)
Présentation
• Un maître mot : MINIMISATION !• Moins de vues équivaut à :
• measure() plus rapide• layout() plus rapide• draw() plus rapide
• Trop de vues :• OutOfMemoryException• LayoutInflater.inflate() long
![Page 51: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/51.jpg)
Présentation
• Un maître mot : MINIMISATION !• Moins de vues équivaut à :
• measure() plus rapide• layout() plus rapide• draw() plus rapide
• Trop de vues :• OutOfMemoryException• LayoutInflater.inflate() long
• Préférez la largeur à la profondeur
![Page 52: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/52.jpg)
Le cas du débutant ... - 1/2
• Création d’un nouveau projet• Utilisation du layout « exemple »
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> </LinearLayout>
![Page 53: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/53.jpg)
Le cas du débutant ... - 1/2
![Page 54: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/54.jpg)
Le cas du débutant ... - 2/2
<?xml version="1.0" encoding="utf-8"?><TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" />
![Page 55: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/55.jpg)
RelativeLayout - 1/2<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="5dp" android:orientation="horizontal">
<ImageView android:id="@+id/image" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:src="@drawable/icon" />
<LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:layout_marginLeft="5dp" android:orientation="vertical"> <TextView android:id="@+id/title" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="5dp" android:textAppearance="?android:attr/textAppearanceLarge" android:text="@string/title" /> <TextView android:id="@+id/subtitle" android:layout_width="fill_parent" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="@string/subtitle" /> </LinearLayout>
</LinearLayout>
![Page 56: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/56.jpg)
RelativeLayout - 1/2
![Page 57: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/57.jpg)
RelativeLayout - 2/2<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="5dp">
<ImageView android:id="@+id/image" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:src="@drawable/icon" />
<TextView android:id="@+id/title" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="5dp" android:layout_toRightOf="@+id/image" android:textAppearance="?android:attr/textAppearanceLarge" android:text="@string/title" />
<TextView android:id="@+id/subtitle" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_toRightOf="@+id/image" android:layout_below="@+id/title" android:textAppearance="?android:attr/textAppearanceMedium" android:text="@string/subtitle" />
</RelativeLayout>
![Page 58: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/58.jpg)
RelativeLayout - 2/2
![Page 59: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/59.jpg)
La balise <merge /> - 1/2
<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent">
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="top|center_horizontal" android:background="@color/default_background" android:src="@drawable/icon" />
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|center_horizontal" android:background="@color/default_background" android:textAppearance="?android:attr/textAppearanceLarge" android:text="@string/title" />
</FrameLayout>
![Page 60: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/60.jpg)
La balise <merge /> - 1/2
![Page 61: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/61.jpg)
• Permet de contourner les limitations de XML
La balise <merge /> - 2/2
<?xml version="1.0" encoding="utf-8"?><merge xmlns:android="http://schemas.android.com/apk/res/android">
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="top|center_horizontal" android:background="@color/default_background" android:src="@drawable/icon" />
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|center_horizontal" android:background="@color/default_background" android:textAppearance="?android:attr/textAppearanceLarge" android:text="@string/title" />
</merge>
![Page 62: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/62.jpg)
La balise <merge /> - 2/2
![Page 63: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/63.jpg)
ViewStub - 1/2
<?xml version="1.0" encoding="utf-8"?><merge xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical">
<!-- ... -->
</LinearLayout>
<include layout="@layout/help" android:id="@+id/help" />
</merge>
![Page 64: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/64.jpg)
ViewStub - 1/2
![Page 65: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/65.jpg)
• Evite les créations de vues rarement utilisées• JIT inflation
ViewStub - 2/2
<?xml version="1.0" encoding="utf-8"?><merge xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" />
<ViewStub android:id="@+id/view_stub" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout="@layout/help" android:inflatedId="@+id/help" />
</merge>
![Page 66: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/66.jpg)
ViewStub - 2/2
findViewById(R.id.view_stub).setVisibility(View.VISIBLE);// ouView inflatedView = ((ViewStub) findViewById(R.id.view_stub)).inflate();
![Page 67: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/67.jpg)
Vues personnalisées
public class CustomView extends View {
public CustomView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); }
@Override protected void onDraw(Canvas canvas) { // Dessin de la vue }
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // Définition de la taille de la vue en fonction des spécifications setMeasuredDimension(100, 100); }}
![Page 68: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/68.jpg)
Layouts personnalisées
public class CustomLayout extends ViewGroup {
public CustomLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); }
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // Définition de la taille de la vue en fonction des spécifications et // des dimensions des vues filles // child.measure(widthMeasureSpec, heightMeasureSpec) }
@Override protected void onLayout(boolean changed, int l, int t, int r, int d) { // Positionnement et dimensionnement de l'ensemble des vues filles // child.layout(left, top, right, int bottom) }}
![Page 69: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/69.jpg)
TextView et Drawable - 1/2
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:orientation="vertical">
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_marginBottom="4dp" android:src="@drawable/icon" />
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:text="@string/not_awesome" />
</LinearLayout>
![Page 70: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/70.jpg)
TextView et Drawable - 1/2
![Page 71: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/71.jpg)
TextView et Drawable - 2/2
<?xml version="1.0" encoding="utf-8"?><TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:drawableTop="@drawable/icon" android:drawablePadding="4dp" android:text="@string/awesome" />
![Page 72: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/72.jpg)
Les outils du SDK
• hierarchyviewer• layoutopt• draw9patch• ddms
![Page 73: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/73.jpg)
UI/Main ThreadLibertéééééééééééé (Braveheart)
![Page 74: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/74.jpg)
Présentation
![Page 75: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/75.jpg)
Présentation
• Le système graphique Android est single threaded• Limitez l’impact sur le UI thread !
![Page 76: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/76.jpg)
Présentation
• Le système graphique Android est single threaded• Limitez l’impact sur le UI thread !
• Conséquences nombreuses• Animations saccadées• ANR• Utilisateur mécontent• Application désinstallée / critiquée ...
![Page 77: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/77.jpg)
Solutions
![Page 78: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/78.jpg)
Solutions
• Java !• synchronize / wait() / notify() / notifyAll()
![Page 79: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/79.jpg)
Solutions
• Java !• synchronize / wait() / notify() / notifyAll()
• java.util.concurrent
![Page 80: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/80.jpg)
Solutions
• Java !• synchronize / wait() / notify() / notifyAll()
• java.util.concurrent• Système de message d’Android
• Handler, Message, Looper, HandlerThread
![Page 81: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/81.jpg)
Solutions
• Java !• synchronize / wait() / notify() / notifyAll()
• java.util.concurrent• Système de message d’Android
• Handler, Message, Looper, HandlerThread
• AsyncTasks
![Page 82: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/82.jpg)
Solutions
• Java !• synchronize / wait() / notify() / notifyAll()
• java.util.concurrent• Système de message d’Android
• Handler, Message, Looper, HandlerThread
• AsyncTasks• IntentService
![Page 83: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/83.jpg)
AsyncTask
private class AsyncTaskStrategy implements LongTaskStrategy {
public void executeTask() { (new DumbTask()).execute((Void[]) null); } private class DumbTask extends AsyncTask<Void, Void, Void> {
@Override protected Void doInBackground(Void... params) { executeLongTask(); return null; }
@Override protected void onPostExecute(Void result) { onLongTaskExecuted(); } }}
![Page 84: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/84.jpg)
Handlerprivate class HandlerStrategy implements LongTaskStrategy { private static final int DUMP_MESSAGE = 0x1234; private DumbHandler mHandler;
public void executeTask() { mHandler = new DumbHandler(); new Thread(new Runnable() { public void run() { executeLongTask(); final Message msg = Message.obtain(mHandler, DUMP_MESSAGE); mHandler.sendMessage(msg); } }).start(); }
private class DumbHandler extends Handler { @Override public void handleMessage(Message msg) { if (msg.what == DUMP_MESSAGE) onLongTaskExecuted(); } }
}
![Page 85: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/85.jpg)
Conclusion
![Page 86: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/86.jpg)
Conclusion
• Utile pour les opérations longues/bloquantes• Entrées / sorties (network & filesystem)• Calculs longs• Accès hardware (Camera.open())
![Page 87: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/87.jpg)
Conclusion
• Utile pour les opérations longues/bloquantes• Entrées / sorties (network & filesystem)• Calculs longs• Accès hardware (Camera.open())
• Classes/méthodes d’aide dans l’API• SharedPreferences.Editor.apply()• AsyncQueryHandler pour les requêtes aux
ContentProviders• Filter.filter(CharSequence, FilterListener)
![Page 88: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/88.jpg)
Conclusion
• Utile pour les opérations longues/bloquantes• Entrées / sorties (network & filesystem)• Calculs longs• Accès hardware (Camera.open())
• Classes/méthodes d’aide dans l’API• SharedPreferences.Editor.apply()• AsyncQueryHandler pour les requêtes aux
ContentProviders• Filter.filter(CharSequence, FilterListener)
• Process.setThreadPriority(int)
![Page 89: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/89.jpg)
GreenDroidUne bibliothèque d’aide au développement
![Page 90: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/90.jpg)
Un triste constat
• Ressenti général médiocre• Peu de qualité• Design / ergo antagonistes
• Framework difficile ?• Trop ouvert• Pas d’aide UI/UX
![Page 91: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/91.jpg)
Pourquoi GreenDroid ?
• La naissance de GreenDroid :• Challenge, opensource, factorisation, etc.• Make Android Market a better place
• La philosophie :• Make Android development consistent and easier
![Page 92: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/92.jpg)
UtilisationImport de la bibliothèque GreenDroid à
votre projet
![Page 93: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/93.jpg)
Utilisation
![Page 94: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/94.jpg)
Utilisation
4 étapes
![Page 95: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/95.jpg)
• Cloner le projet GreenDroid (GitHub)
Utilisation
2
3
4
1
![Page 96: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/96.jpg)
• Cloner le projet GreenDroid (GitHub)
Utilisation
2
3
4
1git clone http://github.com/cyrilmottier/GreenDroid.git
![Page 97: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/97.jpg)
• Appliquer GreenDroid à votre projet Android :• Clic droit > Properties• Android > Library > Add• Sélection du dossier GreenDroid > OK
Utilisation
3
4
1
2
![Page 98: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/98.jpg)
• Hériter des thèmes GreenDroid :• @style/Theme.GreenDroid• @style/Theme.GreenDroid.NoTitleBar• Un thème héritant des thèmes précédents
Utilisation
3
4
1
2
![Page 99: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/99.jpg)
• Hériter des thèmes GreenDroid :• @style/Theme.GreenDroid• @style/Theme.GreenDroid.NoTitleBar• Un thème héritant des thèmes précédents
Utilisation
3
4
1
2
<application android:icon="@drawable/icon" android:label="@string/app_name" android:theme="@style/Theme.GreenDroid"> <!-- ... -->
</application>
![Page 100: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/100.jpg)
• S’assurer que votre application est une GDApplication :• greendroid.app.GDApplication• Votre propre GDApplication
Utilisation
3
4
1
2
![Page 101: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/101.jpg)
• S’assurer que votre application est une GDApplication :• greendroid.app.GDApplication• Votre propre GDApplication
Utilisation
3
4
1
2
<application android:icon="@drawable/icon" android:label="@string/app_name" android:name="greendroid.app.GDApplication" android:theme="@style/Theme.GreenDroid"> <!-- ... -->
</application>
![Page 102: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/102.jpg)
Régles importantes
• Ne modifiez pas GreenDroid !• Utilisation de la notion d’héritage :
• Java pour les classes• XML pour les styles / thèmes
• Pas possible de faire autrement ?• fork• patch• feature request
• N’hésitez pas à patcher / participer !
![Page 103: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/103.jpg)
FonctionnalitésRapide tour d’horizon des possibilités ouvertes
par GreenDroid
![Page 104: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/104.jpg)
ActionBar - 1/2
• Pattern ergonomique :• Affiche le titre de l’écran courant• Donne accès à des actions• Permet le retour à l’écran principal• Présente l’état courant :
• ProgressBar présentant le chargement• Couleur de l’ActionBar fonction du contenu• ...
![Page 105: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/105.jpg)
ActionBar - 2/2
public class ActionBarActivity extends GDActivity {
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setActionBarContentView(R.layout.text); addActionBarItem(Type.Locate, R.id.action_bar_locate); }
@Override public boolean onHandleActionBarItemClick(ActionBarItem item, int position) { switch (item.getItemId()) { case R.id.action_bar_locate:
// Do something break; default: return super.onHandleActionBarItemClick(item, position); } return true; }}
![Page 106: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/106.jpg)
AsyncImageView - 1/2
• ImageView améliorée• Chargement asynchrone d’images
• distantes (http://)• locales (file://)
• Gestion d’un cache• Pré-processing possible
![Page 107: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/107.jpg)
AsyncImageView - 2/2
public class SimpleAsyncImageViewActivity extends GDActivity { private static final String URLS_1 = "https://lh3.googleusercontent.com/_OHO4y8YcQbs/SoWDYIhFrjI/AAAAAAAAKX4/ETS4JGuUYX0/s400/P1080412.JPG"; private static final String URLS_2 = "https://lh6.googleusercontent.com/_OHO4y8YcQbs/So4a6aWih3I/AAAAAAAAKts/hGFcqaHsCuI/s400/P1080809.JPG"; private AsyncImageView mImageView;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setActionBarContentView(R.layout.image); mImageView = (AsyncImageView) findViewById(R.id.image_view); } public void onShowImage1(View v) { mImageView.setUrl(URLS_1); } public void onShowImage2(View v) { mImageView.setUrl(URLS_2); } }
![Page 108: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/108.jpg)
Et bien d’autres ...
• ItemAdapter• QuickActions• ActionBarDrawable• SegmentedBar• etc.
![Page 109: Android Optimisations Greendroid](https://reader031.fdocument.pub/reader031/viewer/2022013101/554d2a1ab4c905c5208b505d/html5/thumbnails/109.jpg)
Questions / Réponses
http://www.cyrilmottier.com@cyrilmottier
Cyril Mottier