Android Concurrency

Notes from AnDevCon IV

Design for correctness upfront
Don’t leak Activities

Possible Solutions

Use threads when needing full control – must handle lifecycle
Non static inner class hold reference to activity
Don’t lock orientation as a solution
Use timeouts for I/O and HTTP
Check for interruption in CPU loops

AsyncTask

Post results back to main UI
Good for lots of small tasks
Not bound to Activity
Bad for long running operations or network I/O
onPre and onPostExecute and onProgress run on main UI thread
can check isCancelled() from doInBackground()
Inconsistent in different API levels

Avoiding Activity Leaks

make it private static
Pass activity as WeakReference
Check Activity for null
cancel in onDestroy()
Managing a Handler could cause a leak

Loaders

Put a single unit of work on a separate Thread
Delivers on the main thread
Continues work during a configuration change
Can monitor data source for change
API level 11+ or 4+ with compatibility library

Loader Usage

Sub class android.support.v4.content.Loader
Managed by LoaderManager
Implement callbacks
loadInBackground can block
Should never contain Activity instances
onLoadFinished called main UI thread
Loader callback can have Activity References

LoaderManager

getSupportLoaderManager()
create call backs in onCreate
pass Loader ID

AsyncTaskLoader

implementation of Loader
Inconsistent

ExecutorServiceLoader

custom implementation
puts all work on a singleton Thread

StateFullLoader

add state to loader too determine if active

Tracking Multiple Loaders

Save loader id’s in onSaveInstanceState()
Read in onCreate()

Tracking Loader Work

use LocalBroadcastManager – part of compatibility library

CursorLoader

queries content providers
Create LoaderCallback with Cursor type
onLoadFinished() use the data

Loaders with Asynchronous APIs

call API in loadInBackground()
use CountDownLatch to block loader thread
API listener should signal the latch

Not for Loaders

lots of small downloads
if needs to run after activity is complete

Services

For very long running operations not tied to Activities
Independent of Activity
have own context
Can be “started” or “bound”

Started Services

can start and stop at any time running as long as needed
must stop the service
manage threading or use IntentService
must figure out how to send data to app

IntentService

Single thread
only runs while work is available
must add to Manifest
override onHandleIntent(Intent) <– run in background
can pass parameters in Intent

Looper, Handler. HandlerThread

Handler schedules and executes work can receive messages and post runnable
Handler has access to single thread
HandlerThread convenience class for creating a new Thread with Looper
HandlerThread could be used as alternative to IntentService

Optimizing for Intermittent I/O

limit to one or two threads
if downloading large files use one thread
only one thread for file I/O per storage device
Runtime.getRuntime().availableProcessors() – 1 threads for CPU intense tasks

Tips

Android has all Java tools (Semaphore, BlockingQueue, etc)
Devices may delay using cores
Avoid polling loops at any cost – use callbacks or blocking
THREAD_PRIORITY_AUDIO sets to higher priority than UI
Compute Renderscript can offload heavy math to GPU

This entry was posted in Uncategorized and tagged . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *