You'll often come across situations in Android development when you'll need to do multiple things at once. A good example of this would be displaying the user interface, while also connecting to an outside source to collect and parse data. This is where threads come in. A thread is a component of a process, and each thread can execute concurrently while sharing computing resources. This means that you can display the user interface and connect to an outside data source at the same time!
AsyncTask & Threads in Android
An AsyncTask utilizes a background thread to perform background operations and display the results on the UI thread. This allows a very easy way of creating threads in Android development. There are four steps each AsyncTask goes through.
- onPreExecute() - This is invoked on the UI thread before the AsyncTask is executed. This method is used to set up an AsyncTask and display some information to the user.
- doInBackground(Params...) - This is where you'll do the actual work the thread will do. This step can also use the publishProgress(Progress...) to publish multiple units of progress which are published to the UI thread in the onProgressUpdate(Progress...) step.
- onProgressUpdate(Progress...) - This is used to display any form of progress to the UI thread and is invoked on the UI thread after a call to publishProgress(Progress...).
- onPostExecute(Result) - This method is invoked on the UI thread once the AsyncTask finishes.
In the Fitness Explorer app I used AsyncTask's to connect to Google Fit and parse the data. Once the data was parsed I returned it to the UI thread.
Connection States & The Observer Pattern
A difficult part of integrating the Google Fit API into the Fitness Explorer app was the need to display connection states. I needed a way to track where I was in the connection process, and to display the various views as necessary. This is what's called the Observer Pattern. The Observer Pattern maintains a list of state changes and notifies any observers of a state change.
To make a method an observer you must subscribe to the method that is constantly changing the state. In the Fitness Explorer app my GoogleFitRepository is the method that you must subscribe to. I pass it an IRepositoryStateChangeListener, which is just an interface listener which constantly checks for a state change.
To represent the various connection states in the Fitness Explorer app I used enums.
While the app is in the CONNECTING state it will display the loading view. The CONNECTION_SUCCESS state will display the dashboard view when connected and there is data, and will display the no data view when there isn't any data. The CONNECTION_FAILED and CONNECTION_CANCELED states will both display the dialog that says the user isn't connected to Google Fit.
We're nearing the end of the series covering Fitness Explorer, and the next sprint will be our last. That sprint will cover putting the final touches on Fitness Explorer using Xuni. It will be a general examination of using data visualizations on Android (especially with Xuni) and wrap up our series.