+ All Categories
Home > Technology > Not Quite As Painful Threading

Not Quite As Painful Threading

Date post: 14-May-2015
Category:
Upload: commonsware
View: 1,224 times
Download: 3 times
Share this document with a friend
Description:
from Apps World Europe 2013
Popular Tags:
22
Copyright © 2013 CommonsWare, LLC Painless Threading Apps World Europe 2013
Transcript
Page 1: Not Quite As Painful Threading

Copyright © 2013 CommonsWare, LLC

Painless Threading

Apps World Europe 2013

Page 2: Not Quite As Painful Threading

Copyright © 2013 CommonsWare, LLC

Painless Threading

Apps World Europe 2013

Not Quite As Painful

Page 3: Not Quite As Painful Threading

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

Page 4: Not Quite As Painful Threading

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

Page 5: Not Quite As Painful Threading

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

Page 6: Not Quite As Painful Threading

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

Page 7: Not Quite As Painful Threading

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

Page 8: Not Quite As Painful Threading

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

Page 9: Not Quite As Painful Threading

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()

Page 10: Not Quite As Painful Threading

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

Page 11: Not Quite As Painful Threading

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

Page 12: Not Quite As Painful Threading

Copyright © 2013 CommonsWare, LLC

Limits of AsyncTask

● Does Not Keep Device Awake● Does Not Keep Process Alive● Still Must Deal with Thread Safety

Page 13: Not Quite As Painful Threading

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

Page 14: Not Quite As Painful Threading

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()

Page 15: Not Quite As Painful Threading

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

Page 16: Not Quite As Painful Threading

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

Page 17: Not Quite As Painful Threading

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

Page 18: Not Quite As Painful Threading

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()

Page 19: Not Quite As Painful Threading

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

Page 20: Not Quite As Painful Threading

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

Page 21: Not Quite As Painful Threading

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

Page 22: Not Quite As Painful Threading

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


Recommended