I have several Activity subclasses in my project, each calling a SOAP based web service, processing and displaying the results. The SOAP serialization, the call handling and the parsing of result into various POJO objects is encapsulated in the MyWebService class. This class executes the actual web service call(s) via an AsyncTask.
For being able to pass back the results to the calling Activity subclass, I figured I enforce that all these activities should implement a WebServiceResultProcessor interface, defining a single function (processWebServiceResults) acting as a callback for the AsyncTask, called from onPostExecute.
I also want to display a ProgressDialog during the web service call. And here comes my question. For being able to display the ProgressDialog (either from MyWebService or it’s AsyncTask), I need to pass a reference to the caller Activity’s Context. And for being able to execute the callback function from the AsyncTask, I also need to pass the same object reference, but this time as a WebServiceResultProcessor. This seems to me a code smell, passing the same object twice, but can’t see any way around that. Instead of interfacing, I could create a new base class, extending the Activity class and enforce inheritance from the extension class, but that would mean I’d exclude ListActivity and the likes from using this MyWebService class.
Is there a better way to do this?
Despite Arhimed’s warning, I ended up using AsyncTask, as it still fits my purposes. I just make sure that all Activities calling web services, upon their
onDestroy(), send acancel()to the invoked AsyncTask. The AsyncTask implementation itself gracefully handles the cancel request by checking isCancelled() everywhere where necessary.As for the original question, I must have had a lapse – the solution is really simple. I pass the Activity subclass instance as an Object to the AsyncTask, and cast it to either Context or to WebServiceResultProcessor, as necessary. Fragments showing how it works:
…