Tips
In situations where we need to make multiple async tasks such as when an activity needs to make multiple recycles views (or fragments), we can reuse the same spinning progress bar widget until all of the async tasks have been completed. The async calls can be used for loading data over network or database or smoother long running tasks. Since the async tasks are happening in the background thread, attempting to start the spinner from the main thread and closing the spinner from background thread would result in exception of type "CalledFromWrongThreadException
" which implies that only the original thread that created a view hierarchy can touch its views.
This can be accomplished by creating two variables, one to store number of requests made and another to store number of requests completed. The assumption is that the async task is an inner class of the calling class. The number of requests made is incremented before calling the async task. And number of requests completed is incremented onPostExecute
function of async
class. progress bar is initialized in the calling class. The progress bar's visibility is set to visible
on start of the async
class. The progress bar's visibility is hidden after onPost
execute and only if the number of requests made is equal to the number of requests completed. Simple!
Below, I am outlining some major steps. I am hoping I would expand this article to add more details in future with full working code.
I defined two private
variables to do count of async tasks in the activity that calls the async tasks. One counter tracks tasks have been requested and the other is for how many have been finished.
private int AsyncTaskCount = 0;
private int AsyncTaskRequested = 0;
private ProgressBar spinner;
Initialize the progress bar on onCreate
method for the calling class.
spinner = (ProgressBar)findViewById(R.id.progressbar);
Update the count of requested say prior to calling the asynctask
:
AsyncTaskRequested = 2;
new NetworkQueryTask().execute(SmartStockConstant.QueryMarket);
new NetworkQueryTask().execute(SmartStockConstant.QueryStock);
On the asynctask
class, update the AsyncTaskCount
in the doInBackground
and set the progress bar visible
:
class NetworkQueryTask extends AsyncTask<String, Void, ArrayList<Stock>> {
private String query;
@Override
protected ArrayList<Stock> doInBackground(String... params) {
AsyncTaskCount++;
spinner.setVisibility(View.VISIBLE);
Finally, onPostExecute
, check if number of completed task equals number of requested and make the progressBar
invisible:
@Override
protected void onPostExecute(ArrayList<Stock> searchResults) {
super.onPostExecute(searchResults);
if(AsyncTaskCount == AsyncTaskRequested) {
spinner.setVisibility(View.GONE);
}
}
}