Android AsyncTask Example
Definition
In software engineering, the delegation pattern is a design pattern in object-oriented programming where an object, instead of performing one of its stated tasks, delegates that task to an associated helper object.
|
Figure 1: simple delegation |
Delegation and Inheritance
In languages such as Java, in which multiple inheritance is not supported, delegation can be used to fill in this gap. From this perspective, delegation is like inheritance done manually through object composition.
|
Figure 2: delegation and inheritance |
More Than Just Inheritance
By using interfaces, delegation can be made more flexible and typesafe.
Flexibility
and
type-safety
here means that the delegator doesn't need to refer to any ClassA or ClassB. As shown by the image below, it can delegate its tasks to any object that implements/conforms to the delegation interface.
|
Figure 3: delegation and interfaces(or protocols) |
The example below shows how
flexibility
and
type-safety
are achieved in delegation pattern by taking advantage of interfaces.
A Use Case - Asynchronous Tasks
Asynchronous tasks run in background. It is vital for a multi-thread program to handle the communication between the background threads and the main thread gracefully. One convenient way of doing so is using delegation pattern where an object, running in the main thread, plays the role of the background operation's delegate, and gets notified of changes in background operation's status such as partial/full completion and errors.
|
Figure 4: delegation and asynchronous tasks |
In the following, a simple Android example of what is discussed above will be explored. This example is created in eclipse IDE on
(Source code available for download). The image below shows screenshots of the app in different stages.
|
Figure 5: sample Android app screenshots |
When the "Start Long Operation" button is pressed, a long operation is started in the background. The long operation notifies the main thread of different stages of the task accomplished so that the main thread can update a progress bar to provide feedback to the user. When the long operation ends, the main thread shows a message to the user saying the task is completed.
Class LongOperation that runs in the background:
The main activity that implements the LongOperationDelegate interface and invokes the background operation:
(Source code available for download)
iOS vs. Android - Delegation pattern
This is actually a comparison between Objective-C protocols and Java interfaces. In Obj-C protocols methods can be defined as optional which means objects conforming to the protocol (
conforming to a protocol
is Obj-C terminology for
implementing an interface
), may or may not implement those methods.
|
Figure 6: an Objective-C protocol |
Whether an object has implemented a method or not can be determined by the caller object using
respondsToSelector
method.
|
Figure 7: caller object uses respondsToSelector method to determine if a method is implemented by other objects |
Optional methods facility makes Obj-C protocols very flexible. This is why iOS Cocoa Touch Framework relies on delegation pattern so heavily.
Java Adapter Classes
Java interfaces can be made more flexible using adapter classes. An adapter class is an abstract class that implements an interface. All the methods of the interface are implemented with an empty body or a body that only throws an exception. Other classes that were supposed to implement the interface directly, will extend the adapter class instead overriding only those methods that are needed. In this way objects do not have to implement a lot of empty and useless methods as a result of implementing an interface.
|
Figure 8: Java adapter classes |
Adapter classes are used in Java API as well. The interface MouseInputListener, which includes many methods, comes with MouseInputAdapter which is an abstract class implementing all methods declared in the interface.