Android rendu et performance - 17 avril 2012

1,713 views

Published on

Published in: Technology, Business
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,713
On SlideShare
0
From Embeds
0
Number of Embeds
475
Actions
Shares
0
Downloads
35
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Android rendu et performance - 17 avril 2012

  1. 1. Lisse comme du beurreRomain Guy, Google@romainguyhttp://www.curious-creature.org/+
  2. 2. Lisse comme du beurreRomain Guy, Google@romainguyhttp://www.curious-creature.org/+
  3. 3. Android ,
  4. 4.  rendu
  5. 5.  et
  6. 6.  performance Lisse comme du beurre Romain Guy, Google @romainguy http://www.curious-creature.org/+
  7. 7. Qui suis-je ? Pourquoi moi ?• Android depuis 2007• Tech-lead du UI toolkit• Je parle beaucoup• J’ai le micro
  8. 8. Ordre du jour• UI thread• Views• Animations• Rendu• Mémoire
  9. 9. UI thread• Ne le bloquez pas ! – Évitez les I/O, lourds calculs, etc.• Mais manipulez la UI depuis ce thread – View.post(Runnable) – Handler
  10. 10. StrictMode1: StrictMode.setThreadPolicy(2: new StrictMode.ThreadPolicy.Builder()3: .detectAll()4: .penaltyDeath()5: .build());
  11. 11. StrictMode1: StrictMode.setThreadPolicy(2: new StrictMode.ThreadPolicy.Builder()3: .detectAll()4: .penaltyDeath()5: .build());
  12. 12. Tâches de fond 1: new Thread(new Runnable() { 2: public void run() { 3: // Opération 4: } 5: }).start();
  13. 13. AsyncTask1: LoadPhotos task =2: new LoadPhotos().execute(romainguy);
  14. 14. 1: class LoadPhotos extends AsyncTaskString, Bitmap, PhotoList { 2: protected PhotoList doInBackground(String... params) { 3: PhotoList photos = Picasa.loadPhotos(params[0]); 4: for (int i = 0; i photos.getCount(); i++) { 5: publishProgress(photos.get(i).loadSmallBitmap()); 6: } 7: return photos; 8: } 9:10: protected void onProgressUpdate(Bitmap... values) {11: addPhotoToGrid(values[0]);12: }13:14: protected void onPostExecute(PhotoList result) {15: setPhotoList(result);16: }17: }
  15. 15. Solution parfaite ? 1: ToggleButton t = (ToggleButton) findViewById(R.id.switchOnOff); 2: t.setOnCheckedChangeListener(new OnCheckedChangeListener() { 3: public void onCheckedChanged(CompoundButton b, boolean isChecked) { 4: new Thread(new Runnable() { 5: public void run() { 6: prefs.edit().putBoolean(switch, isChecked)).commit(); 7: } 8: }).start(); 9: }10: });
  16. 16. Solution parfaite ? 1: ToggleButton t = (ToggleButton) findViewById(R.id.switchOnOff); 2: t.setOnCheckedChangeListener(new OnCheckedChangeListener() { 3: public void onCheckedChanged(CompoundButton b, boolean isChecked) { 4: new Thread(new Runnable() { 5: public void run() { 6: prefs.edit().putBoolean(switch, isChecked)).commit(); 7: } 8: }).start(); 9: }10: });
  17. 17. Ordre d’exécution UI Thread Thread 1 Thread 2 Switch on Switch off
  18. 18. Ordre d’exécution• Processeurs 2/4 coeurs communs• AsyncTask – Sérialisée depuis Android 3.0 – executeOnExecutor()
  19. 19. Une View est coûteuse
  20. 20. Temps Nombre d’attributs XML Inflation
  21. 21. TextView = 800 octetsPoids d’une structure sans les données
  22. 22. Layouts• Coûts supplémentaires d’exécution• La mise en page est coûteuse – RelativeLayout – android:layout_weight• N’appelez pas requestLayout() souvent
  23. 23. Aplatissez vos layouts
  24. 24. ViewStub /
  25. 25. class MyView extends View
  26. 26. new
  27. 27. new
  28. 28. Utilisez les outils !traceview, hierarchyviewer, DDMS lint
  29. 29. View.setLayerType(int type, Paint p)
  30. 30. Button draw()DisplayList Display Save DrawPatch ClipRect Translate DrawText Restore
  31. 31. Button draw() draw()DisplayList Layer Display Save DrawPatch ClipRect Translate DrawText Restore
  32. 32. view.setLayerType(View.LAYER_TYPE_NONE, null) 3 sortes de layers
  33. 33. view.setLayerType(View.LAYER_TYPE_SOFTWARE, null) Layer software
  34. 34. view.setLayerType(View.LAYER_TYPE_HARDWARE, null) Layer hardware
  35. 35. Dessin d’une ListView Layer hardware DisplayList SoftwareTemps en 0.009 2.1 10.3 ms
  36. 36. Opacité Position Taille Rotation Origine alpha x scaleX rotation pivotX y scaleY rotationX pivotY translationX rotationY translationY Propriétés pour transformer les vues
  37. 37. Propriétés de transformation• Ne changent pas la vue• Changent comment elle se dessine• Propices à de nombreuses optimisations
  38. 38. ViewRoot ViewGroup DisplayListView A View B Layer B DisplayList A Optimisation des propriétés
  39. 39. ViewRoot ViewGroup DisplayListView A View B Layer B DisplayList A setRotationY(45) Optimisation des propriétés
  40. 40. ViewRoot ViewGroup DisplayList invalidate()View A View B Layer B DisplayList A setRotationY(45) Optimisation des propriétés
  41. 41. ViewRoot mark dirty ViewGroup DisplayList invalidate()View A View B Layer B DisplayList A setRotationY(45) Optimisation des propriétés
  42. 42. ViewRoot mark dirty ViewGroup DisplayList invalidate()View A View B Layer B DisplayList A setRotationY(45) Optimisation des propriétés
  43. 43. Dure réalité• Les layers ne sont pas gratuits – Coût mémoire important – Créer ou rafraîchir un layer prend du temps• Utilisez les temporairement – Vues complexes – Pour la durée d’une animation
  44. 44. “Property animations”
  45. 45. Nouvelles animations• Animez une propriété – Objet cible – Nom de la propriété – Paramètres de valeurs• Marche avec toute paire get/set
  46. 46. 1: ObjectAnimator.ofFloat(view, alpha, 0);2:3: ObjectAnimator.ofFloat(colorDrawable,4: color, Color.WHITE, Color.BLACK);5:6: ObjectAnimator.ofFloat(view, View.X, 200);
  47. 47. 1: view.setLayerType(View.LAYER_TYPE_HARDWARE, null);2: ObjectAnimator.ofFloat(3: view, View.ROTATION_Y, 180).start();
  48. 48. 1: view.setLayerType(View.LAYER_TYPE_HARDWARE, null); 2: ObjectAnimator animator = ObjectAnimator.ofFloat( 3: view, View.ROTATION_Y, 180); 4: 5: animator.addListener(new AnimatorListenerAdapter() { 6: @Override 7: public void onAnimationEnd(Animator animation) { 8: view.setLayerType(View.LAYER_TYPE_NONE, null); 9: }10: });11:12: animator.start();
  49. 49. Mais il y a mieux !
  50. 50. ViewPropertyAnimator• Plus facile• Plus rapide• Pas de JNI ni de reflection• Optimise les invalidate()
  51. 51. 1: view.animate().alpha(0);2:3: view.animate().translationX(500);4:5: view.animate().alpha(0).translationX(500);
  52. 52. view.animate().rotationY(180).withLayer();
  53. 53. view.animate().rotationY(180).withLayer();
  54. 54. ou ne ai t o u r r u ve r d a n s AP I p tt e s se re t ro ro idCe i t p a e rs i o n d ’An d t ou r ra pe up utu re v e l le -même un e f u r ra i t a se ra i t o ne p i s te r. M a is ç qui s ex êt r e pa b ie n .
  55. 55. Mémoire
  56. 56. $ adb shell dumpsys meminfo process
  57. 57. ** MEMINFO in pid 1523 [com.example.android.sample] ** Shared Private Heap Heap Heap Pss Dirty Dirty Size Alloc Free ------ ------ ------ ------ ------ ------ Native 3260 944 3220 9960 6359 20 Dalvik 6952 15612 6344 21319 16224 5095 Cursor 0 0 0 Ashmem 0 0 0 Other dev 12583 660 1096 .so mmap 1149 1812 352 .jar mmap 0 0 0 .apk mmap 114 0 0 .ttf mmap 7 0 0 .dex mmap 807 0 0 Other mmap 44 8 28 Unknown 1439 356 1424 TOTAL 26355 19392 12464 31279 22583 5115 1 of 2
  58. 58. ** MEMINFO in pid 1523 [com.example.android.sample] ** Shared Private Heap Heap Heap Pss Dirty Dirty Size Alloc Free ------ ------ ------ ------ ------ ------ Native 3260 944 3220 9960 6359 20 Dalvik 6952 15612 6344 21319 16224 5095 Cursor 0 0 0 Ashmem 0 0 0 Other dev 12583 660 1096 .so mmap 1149 1812 352 .jar mmap 0 0 0 .apk mmap 114 0 0 .ttf mmap 7 0 0 .dex mmap 807 0 0 Other mmap 44 8 28 Unknown 1439 356 1424 TOTAL 26355 19392 12464 31279 22583 5115 1 of 2
  59. 59. ** MEMINFO in pid 1523 [com.example.android.sample] ** Shared Private Heap Heap Heap Pss Dirty Dirty Size Alloc Free ------ ------ ------ ------ ------ ------ Native 3260 944 3220 9960 6359 20 Dalvik 6952 15612 6344 21319 16224 5095 Cursor 0 0 0 Ashmem 0 0 0 Other dev 12583 660 1096 .so mmap 1149 1812 352 .jar mmap 0 0 0 .apk mmap 114 0 0 .ttf mmap 7 0 0 .dex mmap 807 0 0 Other mmap 44 8 28 Unknown 1439 356 1424 TOTAL 26355 19392 12464 31279 22583 5115 1 of 2
  60. 60. ** MEMINFO in pid 1523 [com.example.android.sample] ** Shared Private Heap Heap Heap Pss Dirty Dirty Size Alloc Free ------ ------ ------ ------ ------ ------ Native 3260 944 3220 9960 6359 20 Dalvik 6952 15612 6344 21319 16224 5095 Cursor 0 0 0 Ashmem 0 0 0 Other dev 12583 660 1096 .so mmap 1149 1812 352 .jar mmap 0 0 0 .apk mmap 114 0 0 .ttf mmap 7 0 0 .dex mmap 807 0 0 Other mmap 44 8 28 Unknown 1439 356 1424 TOTAL 26355 19392 12464 31279 22583 5115 1 of 2
  61. 61. ** MEMINFO in pid 1523 [com.example.android.sample] ** Shared Private Heap Heap Heap Pss Dirty Dirty Size Alloc Free ------ ------ ------ ------ ------ ------ Native 3260 944 3220 9960 6359 20 Dalvik 6952 15612 6344 21319 16224 5095 Cursor 0 0 0 Ashmem 0 0 0 Other dev 12583 660 1096 .so mmap 1149 1812 352 .jar mmap 0 0 0 .apk mmap 114 0 0 .ttf mmap 7 0 0 .dex mmap 807 0 0 Other mmap 44 8 28 Unknown 1439 356 1424 TOTAL 26355 19392 12464 31279 22583 5115 1 of 2
  62. 62. Objects Views: 45 ViewRootImpl: 1 AppContexts: 2 Activities: 1 Assets: 2 AssetManagers: 2 Local Binders: 13 Proxy Binders: 14 Death Recipients: 0 OpenSSL Sockets: 0SQL heap: 0 MEMORY_USED: 0 PAGECACHE_OVERFLOW: 0 MALLOC_SIZE: 0Asset Allocations zip:/data/app/com.example.android.sample-2.apk:/resources.arsc: 2K 2 of 2
  63. 63. Objects Views: 45 ViewRootImpl: 1 AppContexts: 2 Activities: 1 Assets: 2 AssetManagers: 2 Local Binders: 13 Proxy Binders: 14 Death Recipients: 0 OpenSSL Sockets: 0SQL heap: 0 MEMORY_USED: 0 PAGECACHE_OVERFLOW: 0 MALLOC_SIZE: 0Asset Allocations zip:/data/app/com.example.android.sample-2.apk:/resources.arsc: 2K 2 of 2
  64. 64. Objects Views: 45 ViewRootImpl: 1 AppContexts: 2 Activities: 1 Assets: 2 AssetManagers: 2 Local Binders: 13 Proxy Binders: 14 Death Recipients: 0 OpenSSL Sockets: 0SQL heap: 0 MEMORY_USED: 0 PAGECACHE_OVERFLOW: 0 MALLOC_SIZE: 0Asset Allocations zip:/data/app/com.example.android.sample-2.apk:/resources.arsc: 2K 2 of 2
  65. 65. $ adb shell dumpsys gfxinfo process
  66. 66. Caches:Current memory usage / total memory usage (bytes): TextureCache 1166964 / 25165824 LayerCache 0 / 16777216 GradientCache 0 / 524288 PathCache 0 / 4194304 CircleShapeCache 0 / 1048576 OvalShapeCache 0 / 1048576 RoundRectShapeCache 0 / 1048576 RectShapeCache 0 / 1048576 ArcShapeCache 0 / 1048576 TextDropShadowCache 0 / 2097152 FontRenderer 0 262144 / 262144 FontRenderer 1 262144 / 262144 FontRenderer 2 262144 / 262144Other: FboCache 1 / 16 PatchCache 22 / 512Total memory usage: 1953396 bytes, 1.86 MBView hierarchy: android.view.ViewRootImpl@40b82f70: 45 views, 4.97 kB (display lists)Total ViewRootImpl: 1Total Views: 45Total DisplayList: 4.97 kB
  67. 67. Caches:Current memory usage / total memory usage (bytes): TextureCache 1166964 / 25165824 LayerCache 0 / 16777216 GradientCache 0 / 524288 PathCache 0 / 4194304 CircleShapeCache 0 / 1048576 OvalShapeCache 0 / 1048576 RoundRectShapeCache 0 / 1048576 RectShapeCache 0 / 1048576 ArcShapeCache 0 / 1048576 TextDropShadowCache 0 / 2097152 FontRenderer 0 262144 / 262144 FontRenderer 1 262144 / 262144 FontRenderer 2 262144 / 262144Other: FboCache 1 / 16 PatchCache 22 / 512Total memory usage: 1953396 bytes, 1.86 MBView hierarchy: android.view.ViewRootImpl@40b82f70: 45 views, 4.97 kB (display lists)Total ViewRootImpl: 1Total Views: 45Total DisplayList: 4.97 kB
  68. 68. Caches:Current memory usage / total memory usage (bytes): TextureCache 1166964 / 25165824 LayerCache 0 / 16777216 GradientCache 0 / 524288 PathCache 0 / 4194304 CircleShapeCache 0 / 1048576 OvalShapeCache 0 / 1048576 RoundRectShapeCache 0 / 1048576 RectShapeCache 0 / 1048576 ArcShapeCache 0 / 1048576 TextDropShadowCache 0 / 2097152 FontRenderer 0 262144 / 262144 FontRenderer 1 262144 / 262144 FontRenderer 2 262144 / 262144Other: FboCache 1 / 16 PatchCache 22 / 512Total memory usage: 1953396 bytes, 1.86 MBView hierarchy: android.view.ViewRootImpl@40b82f70: 45 views, 4.97 kB (display lists)Total ViewRootImpl: 1Total Views: 45Total DisplayList: 4.97 kB
  69. 69. Rendu accéléré• Certains opérations sont gratuites• Certains opérations sont peu coûteuses• Certains opérations sont très coûteuses
  70. 70. Très coûteux• View.setAlpha() ou Canvas.saveLayer() – Crée un buffer temporaire – Coûte du temps – Coûte de la mémoire
  71. 71. Gratuit• View.setAlpha() – Avec un layer – LAYER_TYPE_SOFTWARE – LAYER_TYPE_HARDWARE
  72. 72. Très coûteux• Créer un layer – Allocation mémoire – Rendu, surtout layers software• Faites-le en avance – View.buildLayer()• Évitez les invalidate() – Rafraîchit le layer
  73. 73. Peu coûteux• Un layer se dessine VITE• Effets visuels presque gratuits – Fondu (opacité avec alpha) – Filtres de couleurs
  74. 74. Coûteux• Modifier une Paint souvent• Modifier un Bitmap souvent• Modifier un Path souvent• Créer un nouvel objet encore plus coûteux
  75. 75. Gratuit• Transformations – Translation – Rotation 2D et 3D – Mise à l’échelle• Filtrage de texture – Paint.setFilterBitmap(true)• Avec ou sans layer
  76. 76. Optimiser pour le GPU• Redessiner seulement les parties utiles – N’utiliez pas View.invalidate() – Utilisez View.invalidate(l, t, r, b)• Permet de traverser l’arbre de la UI rapidement
  77. 77. Optimiser pour le GPU• Groupez les primitives – Pas bien : boucle de Canvas.drawLine() – Bien : Canvas.drawLines()• Évitez les changements d’état – Minimisez les appels à save() restore()
  78. 78. Optimiser pour le GPU• Groupez les commandes dans cet ordre – Par type – Par Paint – Par Bitmap
  79. 79. 1: c.drawText(...);2: c.drawBitmap(...);3: c.drawLine(...);4: c.drawText(...);5: c.drawBitmap(...);6: c.drawLine(...);7: c.drawText(...);8: c.drawBitmap(...);9: c.drawLine(...); Pas bien
  80. 80. 1: c.drawText(...);2: c.drawBitmap(...);3: c.drawLine(...);4: c.drawText(...);5: c.drawBitmap(...);6: c.drawLine(...);7: c.drawText(...);8: c.drawBitmap(...);9: c.drawLine(...); Pas bien
  81. 81. 1: c.drawText(...);2: c.drawText(...);3: c.drawText(...);4: c.drawBitmap(...);5: c.drawBitmap(...);6: c.drawBitmap(...);7: c.drawLine(...);8: c.drawLine(...);9: c.drawLine(...); Bien
  82. 82. 1: c.drawText(...);2: c.drawText(...);3: c.drawText(...);4: c.drawBitmap(...);5: c.drawBitmap(...);6: c.drawBitmap(...);7: c.drawLines(...); Mieux
  83. 83. Pour plus d’informations• Google I|O 2011 – Android Accelerated Rendering – http://youtu.be/v9S5EO7CLjo• Parleys.com – Various Devoxx talks for the past 4 years• Android Developers – http://d.android.com
  84. 84. Questions et (peut-être) réponses

×