Upgrade to Pro — share decks privately, control downloads, hide ads and more …

DroidCon NYC 2015 Boris Farber: 10 Ways to Improve You App's Performance

Realm
August 28, 2015
33k

DroidCon NYC 2015 Boris Farber: 10 Ways to Improve You App's Performance

Realm

August 28, 2015
Tweet

Transcript

  1. Plan • Rules of thumb while working with data intensive

    apps ◦ Long launch time ◦ Janky scrolling ◦ Unresponsive app
  2. Why memory leaks are dangerous • Holding references to unused

    Activity • Activity holds its layout ==> hold all views
  3. Static References • Activities/fragments etc - they have a life

    cycle • Activity will not be GC-ed • Static references ◦ become dangling "pointers" ◦ m_staticActivity = staticFragment.getActivity()
  4. Listeners leak public class LeakActivity extends Activity { // ...

    @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); NastyManager.getInstance().addListener(this); // ...
  5. Listener's leak + fix @Override public void onDestroy() { super.onDestroy();

    NastyManager.getInstance().removeListener(this); } remove listener
  6. This is a leak public class MainActivity extends Activity {

    // ... Handler handler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // ... handler = new Handler() { @Override public void handleMessage(Message msg) { } }; // ...
  7. This is a leak + fix private static class MyHandler

    extends Handler { private final WeakReference<MainActivity> mActivity; // ... public MyHandler(MainActivity activity) { mActivity = new WeakReference<MainActivity>(activity); // ... } @Override public void handleMessage(Message msg) { } // ... }
  8. Prefer static to non static inner classes • Non static

    Handler --> Activity leak • Both classes have a different lifetime
  9. What you can do Activity Leaks - 1 • Remove

    away static references • Use event bus • Unregister listeners • Prefer static inner classes to non static ones
  10. What you can do Activity Leaks - 2 • Do

    code reviews • Understand your app structure • Use tools (MAT ...) • Print logs on callbacks
  11. Not on UI thread • Images (caching, loading) • Networking

    • JSON • Database access Use Loaders Use libraries
  12. Images • Glide • Picasso • Fresco • ... Different

    design tradeoffs, especially around large image count
  13. Memory • Bitmaps are tricky ◦ Large size ◦ Fragmented

    heap ◦ ... • LRUCache - part of the support library
  14. Networking • Tricky APIs • Many java.net API calls are

    blocking ◦ Streams ◦ Equals of URL class result in DNS call
  15. JSON • Small JSONs - GSON is the best •

    Large JSONs - Jackson, ig-json-parser
  16. What you can do Scrolling • Keep UI thread only

    for UI • Understand concurrency APIs (next bullet) • Use libraries (memory, caching, json ...) • Use loaders
  17. Service • Service methods run on UI thread ! •

    Consider ◦ IntentService ◦ AsyncTask ◦ Executors ◦ HandlerThreads, Handlers and Loopers - Appendix
  18. IntentService • Single threaded • Simple/One job in a time

    • No job system (keep track for jobs) • No way to stop it
  19. AsyncTask • Don't care about result outside of UI •

    Activity lifecycles - can cause a memory leak (rotation) • Changes rapidly (grab latest and add to your project)
  20. System Abuse • Don't call private APIs by reflection •

    Don't call private native methods (NDK/C level) • Don't use Runtime.exec • "adb shell am" to communicate with other process is not something we want to support
  21. Deprecation • API will be removed • Your app will

    not work • No way to update APIs and tools
  22. Deprecation • There is a compelling reason to move ◦

    Security ◦ Correctness ◦ Performance
  23. What you can do around deprecation • Know and use

    APIs • Refactor your dependencies
  24. Newer is better • Prefer Toolbar to ActionBar • Prefer

    RecyclerView (especially for animations)
  25. Don't use Apache Http Connection • Removed at M (still

    available as dependency) • Use HttpURLConnection ◦ Simple API ◦ Small size ◦ Transparent compression ◦ Response caching
  26. What you can do Deprecation • Don't abuse the system

    • Update your dependencies and tools
  27. Work with framework not against ... • Framework components have

    a purpose ◦ Specific semantics ◦ Used when those semantics are desired • Don't over engineer • Keep simple
  28. Pick 3rd party lib checklist • Solves your problem •

    Plays nicely with your current dependencies • Dex method count • Dependencies • Maintenance • Runtime permissions
  29. What you can do Architecture • Consistent • Get people

    on board quickly • Have someone experienced • Pick your dependencies wisely
  30. HandlerThread • A thread with a message box • Saves

    a lot of boilerplate code • Uses Looper
  31. Loopers and Handlers • Looper ◦ Synchronized message queue to

    process messages from handlers ◦ Takes the next task, executes it, then takes the next one and so on ◦ One looper per thread • Handler ◦ Set of methods to post messages
  32. Inside Looper (Android src) private Looper(boolean quitAllowed) { // ...

    mThread = Thread.currentThread(); } /** * Run the message queue in this thread. Be sure to call * {@link #quit()} to end the loop. */ public static void loop() { final Looper me = myLooper(); // ... for (; ; ) { // ... } infinite loop