get off my thread! - keep your ui super-responsive
DESCRIPTION
The importance of keeping the main thread free and ways to do it. We'll cover classic main thread busy pitfalls and classic workaround (IntentService, AsyncTask). We'll also cover useful techniques for getting back to the main thread and Simple synchronization strategies. As presented in DroidCon Tel Aviv 2014 by: Ori Peleg, Facebook http://il.droidcon.comTRANSCRIPT
Get off my thread! Adventures in perceived performance
Ori Peleg Software Engineer DroidCon TLV, June, 2014
1 Our app is stuck
2 Background service
3 Jank hunters never sleep
4 Nonblocking frenzy
5 Conclusion
Agenda
Our app is stuck
Slow activity
▪ App was stuck
▪ ~5 seconds on older devices
Slow activity
▪ App was stuck
▪ ~5 seconds on older devices
▪ ANR :-(
▪ Computed items to display
Make it faster?
▪ The app was still stuck!
▪ Turns out we were Main Thread bandits
▪ Any work done on the main thread
▪ Prevents UI updates
▪ Prevents interaction (touch, back button)
Make it seem faster!
▪ The app was still stuck!
▪ Turns out we were Main Thread bandits
▪ Any work done on the main thread
▪ Prevents UI updates
▪ Prevents interaction (touch, back button)
▪ AsyncTask to the rescue!
Background service still slow
Complex logic in the background
▪ “Make it a service”
▪ The app is super-slow
▪ “Separate process”
▪ The app isn’t stuck, but…
▪ Multi-process adds a lot of complexity
Back to a single process
▪ App takes 10 seconds to load
▪ ANR :-(
▪ Can the service affect the UI’s performance?
▪ (yes)
▪ Many dependent initialization steps
▪ AsyncTask?
Threads
▪ Many things can happen in parallel
▪ Main thread stays free
▪ But we create a lot of threads
Thread pools (Executors)
▪ Reuse threads
▪ Grows as needed
Jank hunters never sleep
Jank hunters
▪ We must fight to keep the main thread free!
▪ Every Activity Service callback is called in the main thread!
▪ Computations – too slow
▪ Network access – too slow
▪ Disk I/O?
▪ Even that is too slow
▪ StrictMode FTW
SharedPreferences
▪ In-memory cache
▪ Fast enough for the main thread
▪ But what about editing?
▪ .commit() flushes to disk (can block)
▪ No guarantees (no fsync)
▪ .apply() is good
Common patterns
▪ Loading images
▪ Picasso, by Square
▪ UI isn’t ready
▪ Progress indicator
▪ Some of the UI isn’t ready
▪ Show later (progress / fade in)
▪ Background processing
▪ IntentService (instead of Service)
Common errors
▪ Activity/Fragment have died while processing
▪ Cancel work in onStop/onDestroy
▪ Check isDestroyed/isAdded
▪ Thread-sensitive code
▪ ThreadLocal
Nonblocking frenzy manageable?
High-Velocity News – the FAST news app
▪ Fetch headlines in topic
▪ Fetch stories before you tap
▪ Simplify Concurrency with Futures™
Futures (Guava’s extensions)
Get news feed (blocking)
Get news feed (Future)
Get news stories (parsed)
Get top news story
Display the news story
Alternatives to the callback chain
▪ Futures.transform
▪ RxJava
Conclusion get off my thread!
Simple rules to follow
▪ Be aware what’s running on which thread
▪ Remember what’s slow
▪ Offload asynchronicity to libraries
▪ Test on typical (vs high-end) devices
▪ Threads/Executors/Futures FTW
Ori Peleg [email protected]