Android Performance Tips & Tricks
Sergii Zhuk
Android Developer at DAXX BV
Kyiv, FrameworksDays Android Saturday, 2015-06-06 1
Agenda
• Effective Java in Android
• Layouts and UI
• Proper Use of Resources
• Dev Tools and Measuring Performance
2
Effective Java in Android
• Avoid using Floating-Point
• Prefer primitives and primitive-backed data
structures (ArrayMap, SparseArray)
• Two parallel (int) arrays are better than array
(int,int)
3
Effective Java in Android
• System.arraycopy() is about 9x faster than a
hand-coded loop
• Make your method static: invocations will be
about 15%-20% faster
• Do not use Enums
WAT??
 @IntDef annotation
4
Supplying Scaled Drawables
• Why not to supply a single xhdpi image as blurred
background for the screen?
• Rendering performance will decrease because
device should scale your image during app
execution
• Such operation requires extra memory for Bitmap
native processing, potential source of
OutOfMemoryError
5
Make Your Layouts Flat
• Inflating layout is a top-down traversal of the
view tree
• Hierarchy Viewer (Android SDK) allows to
analyze layout while your application is
running
6
“Heavy” ViewGroups
• RelativeLayout requires two measurement passes to
ensure that it has handled all of the layout relationships
• The same is valid for LinearLayout with layout weights
• If one of the children of ViewGroups shown above is again
RelativeLayout or LinearLayout with weights – four
measurements passes will be required for sub-hierarchy
• GridLayout could be good solution in some cases (API 14+)
7
GridLayout example
8
Splash Screen Effect
• Show a blank window constructed with the
application theme, including specified
background drawable while application is
starting
• Behavior is provided by OS
9
Splash Screen Effect
10
ViewStub
• A lightweight view with no dimension and
doesn’t draw anything or participate in the
layout
• Use ViewStub as a “lazy include” for sub-
hierarchies that can be optionally inflated
later.
11
Develop for the Low End
• Devices distribution in the world
• Most of users could have lower-end devices
than yours
• Use ActivityManager.isLowRamDevice() to
detect if device in the class of a 512MB RAM
and/or about a 800x480 screen [API 19+]
12
13
Develop for the Low End
* More details at my Stackoverflow.com question
Nexus 4 (Genymotion emu)
and other devices
Lenovo P780 with Android 4.2.1
Remove unused resources
• Lint (Android SDK): will highlight these resources
• Android-resource-remover (consumes Lint
output)
• Gradle:
14
buildTypes {
release {
minifyEnabled true
shrinkResources true
}
}
Multiple APKs on Play Store
• Different APKs for your app that are each
targeted to different device configurations
• Have same app listing on Google Play and must
share the same package name and be signed with
the same release key
• Recommended to use multiple APKs only when
your APK is too large (> 50MB)
15
Gradle Plugin: APK splits
android {
...
splits {
density {
enable true
reset()
exclude "ldpi", "tvdpi", "xxxhdpi"
}
}
16
WARN: you will need to set different version code for each APK file
Developer Options On Your Device
17
Developer Options On Your Device
18
Avoid Requesting a Large Heap
• Requesting a larger heap may be necessary in
some rare situations like media content
• android:largeHeap=“true” result: less memory
to be available for other apps, necessitating
them being killed and restarted
• android:largeHeap seems to be not enough
documented
19
Memory Leaks
• If a chain of references holds an object in
memory after the end of its expected lifetime
• Old approach:
Dump  Fix header  MAT  Find leak
• New approach: LeakCanary will notify you
20
LeakCanary
21
dependencies {
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3.1'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1'
}
public class ExampleApplication extends Application {
@Override public void onCreate() {
super.onCreate();
LeakCanary.install(this);
}
}
LeakCanary
22
* Sometimes you still need MAT
In-app performance check
• StrictMode
• Google’s profiling tools: Traceview &
dmtracedump
• Hugo by Jake Wharton
• Tools like NewRelic to show bottlenecks in
response time
23
References
• http://developer.android.com/training/articles/perf-tips.html
• Chet Haase at Medium: Developing for Android (parts 1-5)
• Memory leaks in Android (in Russian)
• Android Performance Case Study by Romain Guy
• Is Android layout really exponentially hard? SO discussion
• Pro Android Apps Performance Optimization by Herv Guihot
• Eric Lafortune talk on MCE2015 Conference
• Cyril Mottier blog
• Taylor Ling blog
• Romain Guy blog
• Android Performance Patterns (YouTube and G+)
• DOU.ua Android Digest 
24
Thank you!
@sergiizhuk
sergey.public@gmail.com
http://ua.linkedin.com/in/sergiizhuk
25

Android Performance Tips & Tricks

  • 1.
    Android Performance Tips& Tricks Sergii Zhuk Android Developer at DAXX BV Kyiv, FrameworksDays Android Saturday, 2015-06-06 1
  • 2.
    Agenda • Effective Javain Android • Layouts and UI • Proper Use of Resources • Dev Tools and Measuring Performance 2
  • 3.
    Effective Java inAndroid • Avoid using Floating-Point • Prefer primitives and primitive-backed data structures (ArrayMap, SparseArray) • Two parallel (int) arrays are better than array (int,int) 3
  • 4.
    Effective Java inAndroid • System.arraycopy() is about 9x faster than a hand-coded loop • Make your method static: invocations will be about 15%-20% faster • Do not use Enums WAT??  @IntDef annotation 4
  • 5.
    Supplying Scaled Drawables •Why not to supply a single xhdpi image as blurred background for the screen? • Rendering performance will decrease because device should scale your image during app execution • Such operation requires extra memory for Bitmap native processing, potential source of OutOfMemoryError 5
  • 6.
    Make Your LayoutsFlat • Inflating layout is a top-down traversal of the view tree • Hierarchy Viewer (Android SDK) allows to analyze layout while your application is running 6
  • 7.
    “Heavy” ViewGroups • RelativeLayoutrequires two measurement passes to ensure that it has handled all of the layout relationships • The same is valid for LinearLayout with layout weights • If one of the children of ViewGroups shown above is again RelativeLayout or LinearLayout with weights – four measurements passes will be required for sub-hierarchy • GridLayout could be good solution in some cases (API 14+) 7
  • 8.
  • 9.
    Splash Screen Effect •Show a blank window constructed with the application theme, including specified background drawable while application is starting • Behavior is provided by OS 9
  • 10.
  • 11.
    ViewStub • A lightweightview with no dimension and doesn’t draw anything or participate in the layout • Use ViewStub as a “lazy include” for sub- hierarchies that can be optionally inflated later. 11
  • 12.
    Develop for theLow End • Devices distribution in the world • Most of users could have lower-end devices than yours • Use ActivityManager.isLowRamDevice() to detect if device in the class of a 512MB RAM and/or about a 800x480 screen [API 19+] 12
  • 13.
    13 Develop for theLow End * More details at my Stackoverflow.com question Nexus 4 (Genymotion emu) and other devices Lenovo P780 with Android 4.2.1
  • 14.
    Remove unused resources •Lint (Android SDK): will highlight these resources • Android-resource-remover (consumes Lint output) • Gradle: 14 buildTypes { release { minifyEnabled true shrinkResources true } }
  • 15.
    Multiple APKs onPlay Store • Different APKs for your app that are each targeted to different device configurations • Have same app listing on Google Play and must share the same package name and be signed with the same release key • Recommended to use multiple APKs only when your APK is too large (> 50MB) 15
  • 16.
    Gradle Plugin: APKsplits android { ... splits { density { enable true reset() exclude "ldpi", "tvdpi", "xxxhdpi" } } 16 WARN: you will need to set different version code for each APK file
  • 17.
    Developer Options OnYour Device 17
  • 18.
    Developer Options OnYour Device 18
  • 19.
    Avoid Requesting aLarge Heap • Requesting a larger heap may be necessary in some rare situations like media content • android:largeHeap=“true” result: less memory to be available for other apps, necessitating them being killed and restarted • android:largeHeap seems to be not enough documented 19
  • 20.
    Memory Leaks • Ifa chain of references holds an object in memory after the end of its expected lifetime • Old approach: Dump  Fix header  MAT  Find leak • New approach: LeakCanary will notify you 20
  • 21.
    LeakCanary 21 dependencies { debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3.1' releaseCompile'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1' } public class ExampleApplication extends Application { @Override public void onCreate() { super.onCreate(); LeakCanary.install(this); } }
  • 22.
  • 23.
    In-app performance check •StrictMode • Google’s profiling tools: Traceview & dmtracedump • Hugo by Jake Wharton • Tools like NewRelic to show bottlenecks in response time 23
  • 24.
    References • http://developer.android.com/training/articles/perf-tips.html • ChetHaase at Medium: Developing for Android (parts 1-5) • Memory leaks in Android (in Russian) • Android Performance Case Study by Romain Guy • Is Android layout really exponentially hard? SO discussion • Pro Android Apps Performance Optimization by Herv Guihot • Eric Lafortune talk on MCE2015 Conference • Cyril Mottier blog • Taylor Ling blog • Romain Guy blog • Android Performance Patterns (YouTube and G+) • DOU.ua Android Digest  24
  • 25.

Editor's Notes

  • #3 Не будем писать код -- Много кода есть у индусов Магии не будет, будет много простого и правильного
  • #4 Каждый объект – как минимум 8 байт + Специфичные реализации Android, где нет лишних методов – но и нет реализации Map
  • #5 ProGuard: в некоторых случаях может привести enum к int
  • #6 Крешили и Core2 и galaxy s3. Может, на маленькой картинке это работает ок и можно забить
  • #7 Отдельный случай – когда работаете с ViewPager – и держите в памяти 3-5 экранов – тогда тормоза заметны и на быстром устройстве
  • #8 Is Android layout really exponentially hard? discussion http://stackoverflow.com/questions/17493819/is-android-layout-really-exponentially-hard Also sometimes on LinearLayouts with weight
  • #10 <style name="AppBaseTheme" parent="android:Theme.Holo.NoActionBar">     <item name="android:windowBackground">@color/red</item> </style>
  • #12 Первое, что приходит в голову, когда нужно показать часть UI позже: сделать View.GONE ViewStub : нет размеров, ничего не рисует When inflate() is invoked, the ViewStub is replaced by the inflated View and the inflated View is returned. This lets applications get a reference to the inflated View without executing an extra findViewById().
  • #13 Весело – это когда заказчик просит приложение как iOS, забывая, что айфоны стоят в разы дороже среднего андроида
  • #14 Ещё – случай со смартфонами Huawei и неправильными лого
  • #16 Дорого, хлопотно Вопрос в том – готов ли ваш заказчик за это платить. Цукерберг хвастался FBLight – меньше 1Мб
  • #20 Есть такой соблазн Якобы понижает вероятность OutOfMemory
  • #22 Встраивается в ваше приложение, инициализируется одной строчкой кода, Подключается в gradle в режимах debugCompile и releaseCompile (пустая)
  • #23 Пьер из команды Square в начале мая релизнул. 3.5К звёзд в гитхабе за месяц Удобно при тестировании приложения – больше не нужно подключать и ручками сливать дампы: удобно для тестировщиков
  • #24 StrictMode to catch accidental disk or network access on the application's main thread, NewRelic: удобно собирает статистику по времени выполнения каждого метода на различных девайсах Не забудьте убрать все свои логи перед выкатом в продакшен.