The “Login” from Android examples implemented
AsyncTask as a non-static inner class. However, according to Commonsguys, this class should be static and use weak-reference to the outside activity see this.
So what is the correct way to implement
AsyncTask? Static or non-static?
Log in example from Google
If it depends on a specific situation, then with
ListView items (text + plus Bitmap) loaded from the internet using
HttpClient, how should I implement my AsyncTask?
In general I would recommend the static implementation (though both are acceptable).
The Google approach will require less code but your asynctask will be tightly coupled with your actitivy (which means not easily reusable). But sometimes this approach is more readable.
With the CommonsGuy approach, it will require more effort (and more code) to decouple activity and asynctask, but in the end you will have a more modular, more reusable code.
There’s no single “correct” way of implementing
AsyncTask. But here are my two cents:
This class is intended to perform “light” work in the context of an Activity. That’s why it has the methods
onPostExecute running in the UI thread, so that they can access fields and update GUI quickly. Any task that might take a longer time to complete and it is not meant to update a specific activity should be moved to a Service.
Those methods are mostly used to update the GUI. As the GUI is something related to the Activity instance (the fields are likely declared as private member variables), it is more convenient to implement the
AsyncTask as a non-static nested class. It is also the most natural way in my opinion.
In case the task is going to be reused in other activities, I think it should be allowed to have its own class. To be honest, I’m no fan of static nested classes, especially inside views. If it is a class it means it is conceptually different than the activity. And if it is static it means it is not related to this concrete instance of the activity. But as they are nested, those classes are visually inside the parent class making it harder to read, and can go unnoticed in the project package explorer as it only shows files. And despite being less coupled than inner classes, this is not really that useful: if the class changes, you have to merge/commit the whole parent file to the version control. If you where to reuse it, then you’ll have to access it as
Parent.Nested everywhere. So in order to not to couple other activities to the
Parent class, you probably would like to refactor it and extract the nested class to its own file.
So for me the question would be Inner Class vs Top-Level Class.
The linked article already says it
This does emphasize, though, that you want doInBackground() of your AsyncTask to be completely decoupled from the Activity. If you only touch your Activity on the main application thread, your AsyncTask can survive the orientation change intact.
Don’t touch the Activity (e.g. its members) from the
AsyncTask, which is in line with Static Nested Classes
Static Nested Classes
As with class methods and variables, a static nested class is associated with its outer class. And like static class methods, a static nested class cannot refer directly to instance variables or methods defined in its enclosing class — it can use them only through an object reference.
And according to this Static nested class in Java, why?, I would first go with the static inner class and resort to the non-static version only, if it is really necessary.
I found out that a non-static nested Asynctask UI update is faster when you need to update your UI frequently by calling runOnUiThread in onProgressUpdate. For example, when you have to append lines to a TextView.
It’s 1000x faster than implementing listeners for a static AsyncTask. I might be wrong, but that was my experience.