Upload
commonsware
View
1.224
Download
3
Tags:
Embed Size (px)
DESCRIPTION
from Apps World Europe 2013
Citation preview
Copyright © 2013 CommonsWare, LLC
Painless Threading
Apps World Europe 2013
Copyright © 2013 CommonsWare, LLC
Painless Threading
Apps World Europe 2013
Not Quite As Painful
Copyright © 2013 CommonsWare, LLC
Problem #1: Jank
● Sluggish UI Response to User Input– Example: hiccups while scrolling a list
● Reason: Too Much Time Spent on Main Application Thread– 60 fps UI updates 16 ms/frame need to → →
spend < 1ms per callback method● Limitation: Cannot Modify UI from
Background Thread
Copyright © 2013 CommonsWare, LLC
Problem #2: Changes
● Configuration Changes– Example: rotate the device
● Default Behavior = Destroy/Recreate UI– Activities and (most) fragments
● What We Do Not Want: Lost Results– Spin off a thread, which updates the former UI,
not the current UI
Copyright © 2013 CommonsWare, LLC
Problem #3: Sleep
● Devices Fall Asleep After Inactivity– Screen goes dark, CPU powers down– Can be in as little as 15 seconds
● Less if user presses POWER button directly
● What We Do Not Want: Incomplete Work– Spin off thread to do network I/O, fall asleep
mid-conversation, with messed up results
Copyright © 2013 CommonsWare, LLC
Problem #4: Cores
● Good News! We Have Multiple Cores Now!– Better responsiveness from CPU-intensive apps,
such as games● Bad News! We Have Multiple Cores Now!
– Thread safety now a bigger problem than before– Can have results ranging from outright crashes
to subtle inconsistencies
Copyright © 2013 CommonsWare, LLC
Timing Is Everything
● General Transactional Recipe– 1 ms to 1 s use → AsyncTask and retained
fragment– 1-15 s use → IntentService and event bus– 15+ s use wakeful pattern and event bus→
● Also if the work is triggered outside the UI, such as via a push message
Copyright © 2013 CommonsWare, LLC
AsyncTask
● Quick Work– Disk and database I/O– Trivial network I/O (e.g., downloading
thumbnails)● Android Supplies Thread Pool● Android Gives You Hook to Send Results to
Main Application Thread
Copyright © 2013 CommonsWare, LLC
SimpleAsyncTask● https://gist.github.com/commonsguy/6900714
● AsyncTask Subclass, Simpler API– Override doInBackground() and do the work that will
take a moment● Called on a framework-supplied background thread
– Override onPostExecute() and update the UI based on the background work
● Called on main application thread once doInBackground() completes
– Create instance, call execute()
Copyright © 2013 CommonsWare, LLC
AsyncTask
● What AsyncTask Itself Gives You– Optional parameters from execute() to doInBackground()
– Optional results from doInBackground() passed to onPostExecute()
– Additional hooks, like onPublishProgress()– Thread pool choices
● Cost: a bit of complexity
Copyright © 2013 CommonsWare, LLC
Retained Fragment
● setRetainInstance(true)● Effects
– Fragment not destroyed and recreated on configuration change
– onPostExecute() can work with fragment to update UI, will affect the appropriate widgets depending on timing
Copyright © 2013 CommonsWare, LLC
Limits of AsyncTask
● Does Not Keep Device Awake● Does Not Keep Process Alive● Still Must Deal with Thread Safety
Copyright © 2013 CommonsWare, LLC
IntentService
● Use Case– Work that needs to be completed even if user
leaves your UI (e.g., presses HOME)...– ...but not so long that the device is likely to fall
asleep while you are doing that work● Benefits
– Lets Android know that you are doing work– Immune to configuration changes
Copyright © 2013 CommonsWare, LLC
IntentService Recipe
● Extend IntentService– Override onHandleIntent(), where you do
work on framework-supplied background thread● Add <service> to Manifest● Call startService() to Trigger Work
– Takes Intent to identify the service– Package extras on Intent for work details– Intent supplied to onHandleIntent()
Copyright © 2013 CommonsWare, LLC
Event Bus
● Loose Coupling for Result Delivery– LocalBroadcastManager
● Part of Android Support package
– greenrobot's EventBus– Square's Otto
● Not as thread-savvy and so may not be suitable
Copyright © 2013 CommonsWare, LLC
Event Bus Recipe
● UI Layer Receives Events– Register in onResume(), unregister in onPause()
● IntentService Sends Events– Picked up by UI layer if in foreground, to do
what's needed– If not picked up, detect and raise a Notification, if appropriate
Copyright © 2013 CommonsWare, LLC
Limits of IntentService
● No Direct UI Access– Message-based for work requests and results
● Does Not Keep Device Awake● Still Must Deal with Thread Safety
– IntentService itself is single-threaded, so multiple commands are not a problem
– ...but may still have other code accessing same data on main application thread, other threads
Copyright © 2013 CommonsWare, LLC
WakefulIntentService● http://github.com/commonsguy/cwac-wakeful
● Keeps Device Awake During Work● Recipe
– Download JAR
– Extend WakefulIntentService instead of IntentService
– Override doWakefulWork() instead of onHandleIntent()
– Trigger work via sendWakefulWork()
Copyright © 2013 CommonsWare, LLC
WakefulBroadcastReceiver
● Alternative to WakefulIntentService– Ships with Android Support package
● Recipe– Have work be triggered by broadcast to a subclass of WakefulBroadcastReceiver
– Use startWakefulService() in onReceive()
– IntentService calls completeWakefulIntent() when work done
Copyright © 2013 CommonsWare, LLC
Limits of Wakeful Approaches
● No Direct UI Access– Still using event bus for delivering results
● Still Must Deal with Thread Safety● Power Consumption
– Require WAKE_LOCK permission– You may appear in “battery blame screen” in
Settings
Copyright © 2013 CommonsWare, LLC
Recap
● General Transactional Recipe– 1 ms to 1 s use → AsyncTask and retained
fragment– 1-15 s use → IntentService and event bus– 15+ s use wakeful pattern and event bus→
● Also if the work is triggered outside the UI, such as via a push message
Copyright © 2013 CommonsWare, LLC
Code!● https://github.com/commonsguy/cw-omnibus
● SimpleAsyncTask/Retained Fragment– /Threads/SimpleAsyncTask
● AsyncTask/Retained Fragment– /Threads/AsyncTask
● WakefulIntentService/Event Bus– /EventBus