Advertisement
Advertisement

More Related Content

Advertisement

Efficient Android Threading

  1. Efficient Android Threading Anders Göransson anders.goransson@jayway.com www.jayway.com www.jayway.com/blog www.oredev.org
  2. Agenda Optimize UI thread execution Threads on Android Asynchronous Techniques
  3. Threads on Android Android Linux App Process UI Java Threads Native Threads BG BG BG
  4. Threads on Android Android Scheduling Process level: 1. Foreground 2. Visible Android App 3. Service 4. Background
  5. Threads on Android Android Scheduling Foreground Thread Group Process level: App A 1. Foreground > 90% App A 2. Visible Background Thread Group 3. Service App B App B 4. Background < 10%
  6. Threads on Android Android Scheduling Foreground Thread Group Process level: App A 1. Foreground > 90% App A 2. Visible Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); Background Thread Group 3. Service App B App B 4. Background < 10%
  7. Threads on Android Lifecycles Threads Linux Process UI BG BG BG Java Objects Activity Service Android Components Activity Service Broadcast Content Receiver Provider Broadcast Content Receiver Provider
  8. Threads on Android Native Thread Lifecycle Linux Process UI Process BG Application Application Time Start End
  9. Threads on Android Example: Activity Lifecycle Activity Component onCreate() onDestroy() onCreate() onDestroy() Activity Object new() GC Activity Object new() GC Time
  10. Threads on Android Example: Activity Lifecycle Activity Component onCreate() onDestroy() onCreate() onDestroy() BG Start Reference Activity Object new() Activity Object new() Time
  11. Threads on Android Background Threads • A thread is a GC root • Implement cancellation policy for your background threads!
  12. Use Cases UI BG UI BG Thread Thread Thread Thread Get off the Get off the UI thread UI thread early! early! Do long Do long running task running task Report result or update UI
  13. Goal What technique shall I use for my background thread execution?
  14. Asynchronous Techniques • Thread • Executor • HandlerThread • AsyncTask • Service • IntentService • AsyncQueryHandler • Loader
  15. Thread • Plain old Java Thread
  16. Thread Creation and Start Anonymous Inner Class External Class new Thread(new Runnable() { Thread t = new MyThread(); public void run() { t.start(); // Do long task } }).start(); Implicit reference to outer class
  17. Thread Pitfalls • Non-retained threads • Missing cancellation policy • Starting over and over again
  18. Thread Good Use Cases • One-shot tasks • Post messages to the UI thread at end.
  19. One shot tasks Thread
  20. Executor • Powerful task execution framework. public interface Executor { public void execute(Runnable r); } Executor Executor Service ThreadPool Executor
  21. Executor ExecutorService Task submission: executorService.submit(MyTask); executorService.invokeAll(Collection<Tasks>); executorService.invokeAny(Collection<Tasks>); Lifecycle management: executorService.shutdown(); executorService.shutdownNow(); Lifecycle observation: executorService.isShutdown(); executorService.isTerminated(); executorService.awaitTermination(); shutdown() Shutting Terminate Running d Down
  22. Executor Task / Execution Environment Task: Independent unit of work executed anywhere Runnable Callable run() call() Task manager/observer: Future isDone() isCancelled() cancel() Future future = executorService.submit(Callable); Execution Environment: Technique used to execute the task Executor execute(Runnable)
  23. Executor Thread Pools • Executor managing a pool of threads and a work queue. • Reduces overhead of thread creation
  24. Executor Thread Pools Fixed Thread Pool Executors.newFixedThreadPool(3) Cached Thread Pool Executors.newCachedThreadPool() Single Thread Pool Executors.newSingleThreadExecutor() Custom Thread Pool new ThreadPoolExecutor(corePoolSize, maximumPoolSize, aliveTime, unit, workQueue)
  25. Executor Pitfalls • Lost thread safety when switching from sequential to concurrent execution
  26. Executor Good Use Cases • Execute tasks concurrently • Multiple Http requests • Concurrent image processing • Use cases gaining performance from concurrent execution. • Lifecycle management and observation of task execution. • Maximum platform utilization
  27. Execution abstraction Repetitive tasks Concurrent execution Sequential execution One shot tasks Execution management Task management Thread Executor
  28. HandlerThread • Inherits from Thread and encapsulates a Looper-object. • Thread with a message queue and processing loop. • Handles both Message and Runnable. t = new HandlerThread().start(); t.quit() Running Dead
  29. HandlerThread How it works Create and Start Handler 1 Thread Message Queue Add Process 3 2 1 2 t = new HandlerThread("BgThread"); Handler h = new Handler(t.getLooper()) { t.start(); @Override public void handleMessage(Message msg) { //Process message 3 } h.sendEmptyMessage(42); };
  30. HandlerThread Handler Runnable/Message submission: post(Runnable); postDelayed(Runnable); postAtTime(Runnable) postAtFrontOfQueue(Runnable); sendMessage(Message); Lifecycle management: sendMessageDelayed(Message); sendMessageAtTime(Message); sendMessageAtFrontOfQueue(Message); Runnable/Message removal: removeCallbacks(Runnable); removeMessages(Message)
  31. HandlerThread Good Use Cases • Keep a thread alive • Sequential execution of messages • Avoid concurrent execution on multiple button clicks • State machine • Detailed control of message processing.
  32. Execution abstraction Repetitive tasks Concurrent execution Sequential execution One shot tasks Execution management Task management Thread Executor One shot tasks Concurrent execution “newSingleThreadExecutor”-alike Execute Message and Runnable Better clean up Handler Thread
  33. AsyncTask • Wraps Handler/Looper thread communication. • Utilizes the Executor framework. • Callbacks for UI operations and Background operation.
  34. AsyncTask How it works UI BG Thread Thread new AsyncTask.execute() 1 onPreExecute() 2 doInBackground() 3 AsyncTask.cancel() onCancelled() onPostExecute() 4b 4a
  35. AsyncTask How it works public class MyActivity extends Activity { public void onButtonClicked(View v) { new MyAsyncTask().execute("SomeInputString"); } } public class MyAsyncTask extends AsyncTask<String, Void, Integer> { @Override protected void onPreExecute() { } @Override protected Integer doInBackground(String... params) { return null; } @Override protected void onCancelled(Integer result) { } @Override protected void onPostExecute(Integer result) { } }
  36. AsyncTask Pitfalls • Application Global Behavior • execute() • Cancellation • Creation and Start
  37. AsyncTask > Pitfalls Application Global Behavior Servic e execute() Activity execute() Queue Thread Pool Activity execute() Receiver execute() * execute()
  38. AsyncTask > Pitfalls execute() Execution behavior has changed over time < Donut: execute() < Honeycomb: execute() >= Honeycomb: execute() executeOnExecutor(Executor)
  39. AsyncTask > Pitfalls execute() “So, if I call AsyncTask.execute on Honeycomb and later my tasks will run sequentially, right?” “Right?!?” “Eh, it depends…” <uses-sdk android:targetSdkVersion="12" /> <uses-sdk android:targetSdkVersion="13" />
  40. AsyncTask > Pitfalls Cancellation • Cancel AsyncTask when component finishes lifecycle. • Avoid UI updates on unavailable component. • cancel(true) == cancel(false) + interrupt() • Implement cancellation policy.
  41. AsyncTask > Pitfalls Creation and Start • at = new AsyncTask() • The first creation decides callback thread • onPostExecute() • onPublishProgress() • onCancelled() • at.execute() • Callback thread of onPreExecute()
  42. Execution abstraction Repetitive tasks Concurrent execution Sequential execution One shot tasks Execution management Task management Thread Executor Concurrent execution Task control “newSingleThreadExecutor” AsyncTask<Void, Void, Void> Execute Message and Runnable AsyncTask.execute(Runnable) Better clean up Handler Thread Subsequent execution AsyncTask One task with UI callback
  43. Service • Background execution on the UI thread • Decouple background threads with other lifecycles, typically the Activity lifecycle.
  44. Service Example: Lifecycle Decoupling Activity Component onCreate() onDestroy() onCreate() onDestroy() Service Component onCreate() onDestroy() BG Time
  45. Service Good Use Cases • Tasks executed independently of user interaction. • Tasks executing over several Activity lifecycles or configuration changes.
  46. Service Pitfalls • Hidden AsyncTask.execute() with serial execution.
  47. Execution abstraction Repetitive tasks Concurrent execution Sequential execution One shot tasks Execution management Task management Thread Executor Concurrent execution Task control “newSingleThreadExecutor” AsyncTask<Void, Void, Void> Execute Message and Runnable AsyncTask.execute(Runnable) Better clean up Handler Thread Subsequent execution AsyncTask Service Activity lifecycle One task with UI callback independent tasks
  48. IntentService • Service with a worker thread. • On demand intents. public class MyIntentService extends IntentService { @Override protected void onHandleIntent(Intent intent) { } }
  49. IntentService Lifecycle IntentService Component onCreate() onDestroy() BG Intent 1 Intent 2 Intent 3 Intent n stopSelf() Time
  50. IntentService Good Use Cases • Serially executed tasks decoupled from other component lifecycles. • Off-load UI thread from BroadcastReceiver. • REST client (ResultReceiver as callback)
  51. Execution abstraction Repetitive tasks Concurrent execution Sequential execution One shot tasks Execution management Task management Thread Executor Concurrent execution Task control “newSingleThreadExecutor” AsyncTask<Void, Void, Void> Execute Message and Runnable AsyncTask.execute(Runnable) Better clean up Handler Thread Subsequent execution “On “Continuous” demand” Intent AsyncTask Service Service Activity lifecycle One task with UI callback independent tasks
  52. AsyncQueryHandler • API Level 1 • Asynchronous operations on a ContentResolver • Query • Insert • Delete • Update • Wraps a HandlerThread
  53. AsyncQueryHandler How it works UI BG Thread Thread new AsyncQueryHandler(); 1 startQuery(); startInsert(); startUpdate(); startDelete(); 2 DB operations 3 onQueryComplete(); onInsertComplete(); onUpdateComplete(); onDeleteComplete();
  54. AsyncQueryHandler Cons • No cursor management • No content observation • No data retention on configuration changes • Background thread can’t be forced to quit
  55. Execution abstraction Repetitive tasks Concurrent execution Sequential execution Asynchronous CRUD One shot tasks Execution management Task management Async Thread Executor Query Handler Concurrent execution Task control “newSingleThreadExecutor” AsyncTask<Void, Void, Void> Execute Message and Runnable AsyncTask.execute(Runnable) Better clean up Handler Thread Subsequent execution “On “Continuous” demand” Intent AsyncTask Service Service Activity lifecycle One task with UI callback independent tasks
  56. Loader • API added in Honeycomb • Available in compatibility package • Load data in a background thread • Observes data changes • Retained on configuration changes • Connected to the Activity and Fragment lifecycles
  57. Loader Basics 3 Lifecycle management 4 Retained on configuration change Loader 1 Load data in BG 2 Observe data Data Source
  58. Loader Data Sources Custom Cursor Loader Loader Any Data Content Source Provider
  59. Loader How It Works public class AndroidLoaderActivity extends ListActivity implements LoaderCallbacks<Cursor>{ SimpleCursorAdapter mAdapter; public void onCreate(Bundle savedInstanceState) { getLoaderManager().initLoader(0, null, this); } @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { return new CursorLoader(..., CONTENT_URI, ...); } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor c) { mAdapter.swapCursor(c); } @Override public void onLoaderReset(Loader<Cursor> arg0) { mAdapter.swapCursor(null); } }
  60. Loader Pitfalls • Data loading will stop when Activity/Fragment is destroyed • Http requests not finished
  61. Loader Good Use Cases • Loading data from Content Providers.
  62. Execution abstraction Repetitive tasks Concurrent execution Sequential execution Asynchronous CRUD One shot tasks Execution management Task management Async Thread Executor Query Handler Concurrent execution Task control Full CRUD “newSingleThreadExecutor” AsyncTask<Void, Void, Void> Execute Message and Runnable Load data from CP AsyncTask.execute(Runnable) Better clean up Data observing Handler Custom Thread Loader Subsequent execution Loader “On “Continuous” demand” Intent AsyncTask Service Service Activity lifecycle One task with UI callback independent tasks
  63. Thank you for listening! Questions?

Editor's Notes

  1. Android app has only UI thread from the startJava threads = Native Linux threads
  2. A Java Object goes through one Component lifecycle
  3. A Java Object goes through one Component lifecycle
  4. Compare different techniques to handle background execution.
  5. Future compatibility with more CPUs
  6. Future compatibility with more CPUs
  7. A Java Object goes through one Component lifecycle
  8. A Java Object goes through one Component lifecycle
Advertisement