Showing posts with label callbacks. Show all posts
Showing posts with label callbacks. Show all posts

31 August 2016

callback on thread completion

The code illustrate how callback is being accomplished on Thread completion:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Executor {

  public <T> void execute(Callable<T> task, BiConsumer<T, ? super Exception> callback) {
     CallableThread<T> thread = new CallableThread<>(task, callback);
     thread.start();
  }

  class CallableThread<T> extends Thread {

     Callable<T> task;
     BiConsumer<T, ? super Exception> callback;

     public CallableThread(Callable<T> task, BiConsumer<T, ? super Exception> callback) {
        this.task = task;
        this.callback = callback;
     }

     public void run() {
        System.out.println("running task on thread : " + Thread.currentThread().getName());
        try {
            T t = task.call();
            callback.accept(t, null);
        } catch (Exception ex) {
            callback.accept(null, ex);
        }
     }
   }
 }

Caller:
1
2
3
4
5
6
7
8
System.out.println("running task on thread : " + Thread.currentThread().getName());

new Executor().execute(() -> "HELLO WORKD", (result, ex) -> {
    System.out.println("result: " + result);
    System.out.println("exception: " + ex);
});

System.out.println("finished running task on thread : " + Thread.currentThread().getName());


Output:
1
2
3
4
5
running task on thread : main
finished running task on thread : main
running task on thread : Thread-0
result: HELLO WORKD
exception: null

It appears that, the Executor is submitting the Callable to execution and on complete it invokes the callback functional interface.


01 October 2011

Centralize your NSURLConnection code while using Async connections

We should use Aysnc calls when dealing with NSURLConnections. May articles illustrate why we should do that, among them is this one The truth about synchronous NSURLConnection. Also see my question on SO. But We want also to have our "Communicate" code grouped somewhere not to be implemented by all of our classes in the project. This post is talking about how to solve this issue.. Thanks to AliSoftware . Well, We will have some Utility class the doing the connection and handle the data for us.. but what will we do when we got the data from the server? we should call some method on the caller class (in cases, it is a ViewContoller).. so we should send the target class and the selector to be called when the connection done receiving data. So, Here's the code (quick and dirty) for the URLCaller class:
  1. 
  2. #import <Foundation/Foundation.h>
  3. 
  4. @interface URLCaller : NSObject
  5. {
  6.     NSMutableData* data;
  7.     NSObject* target;
  8.     SEL selector;
  9. }
 10. @property (nonatomic, retain) NSMutableData* data;
 11. @property (nonatomic, retain) NSObject* target;
 12. @property (nonatomic) SEL selector;
 13. 
 14. -(id) initWithTarget:(NSObject*) target selector:(SEL)selector;
 15. -(void) call:(NSString*) url;
 16. 
 17. @end
 18. 
 19. 
 20. #import "URLCaller.h"
 21. 
 22. @implementation URLCaller
 23. @synthesize data, target, selector;
 24. 
 25. -(id) initWithTarget:(NSObject*) _target selector:(SEL)_selector
 26. {
 27.     if (self = [super init])
 28.     {
 29.         self.target = _target;
 30.         self.selector = _selector;
 31.     }
 32.     return self;
 33. }
 34. 
 35. -(void) call:(NSString*) url
 36. {
 37.     NSURLConnection* connection = [[NSURLConnection alloc]initWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:url]] delegate:self];
 38.     [connection release];
 39. }
 40. 
 41. #pragma mark - NSURLConnection deleages
 42. 
 43. -(void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response
 44. {
 45.     data = [[NSMutableData alloc] init]; // _data being an ivar
 46. }
 47. -(void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)_data
 48. {
 49.     [self.data appendData:_data];
 50. }
 51. -(void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error
 52. {
 53.     // Handle the error properly
 54. }
 55. -(void)connectionDidFinishLoading:(NSURLConnection*)connection
 56. {
 57.     NSString* stringData = [[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]autorelease];
 58.     [target performSelector:selector withObject:stringData];
 59. }
 60. 
 61. - (void)dealloc 
 62. {
 63.     [target release];
 64.     [data release];
 65.     [super dealloc];
 66. }
 67. 
 68. @end
And in the caller class (in my case is a ViewController), we will use the URLCaller class:
  1. 
  2. -(IBAction)getDataFromServer:(id)sender
  3. {
  4.     URLCaller* caller = [[URLCaller alloc]initWithTarget:self selector:@selector(setTextViewContents:)];
  5.     [caller call:@"http://search.twitter.com/search.json?q=Muhammad"];
  6.     [caller release];
  7. }
  8. 
  9. // this will got called when the data returned from the server
 10. -(void) setTextViewContents:(NSString*) contents
 11. {
 12.     text.text = contents;
 13. }
You can get the project source code from here Very important notice is that, the application will never got freeze while the data is being transferred, and this is what we wants!

26 August 2011

Implemet callbacks using callback interfaces

SA,

While I am fasting now (there are about 2 hours left for the breakfast), I'd like to talk about some very important usage of interfaces...

I am here by interfaces mean the types that contains only function prototypes.
The interfaces found in many programming language like Java, C# and others.

I'll not talk about any particular programming language here, although, the code samples will be pseudocode.

Suppose We want to build some Generic function that draw a button on the screen and execute it:
1.
2.
3.
4.
5.
6.
7.
void drawButton(Panel container, String buttonName)
{
    Button b = new Button();
    b.setName(buttonName);
    container.add(b);

}
Now we need to add the functionality to the button, but remember this is a generic module, so the functionality will be provided by the module user.

We can modify our code to appear like:
1.
2.
3.
4.
5.
6.
7.
8.
void drawButton(Panel container, String buttonName, int (*onClick) (Button b))
{
    Button b = new Button();
    b.setName(buttonName);
    container.add(b);
    (*onClick) (b);
    
}

Now, the use can send a pointer to a function that will execute the action when the button is clicked.

The solution above can work for language that support function pointers such as C, C++ (Javascript also support passing functions as parameters, and FP langs too)

But what is the language doesn't support function pointers such as Java..

In this case, Interfaces are used and it called then, Callback interfaces...

Let's rewrite our sample:
1.
2.
3.
4.
5.
6.
7.
8.
Button drawButton(Panel container, String buttonName, Clickable clickable)
{
    Button b = new Button();
    b.setName(buttonName);
    container.add(b);
    clickable.onClick(b);
    return b;
}
And here's the code Clickable interface:
1.
2.
3.
4.
5.
public interface Clickable
{
     public void onClick(Button b);
}

So The user to call the above function, it should provide an implementation for the Clickable interface and its onClick function.

Example calling the function:

1.
2.
3.
4.
5.
6.
7.
8.
9.
drawButton(containerPanel, "Go To HomePage", new Clickable()
{
    public void onClick(Button b)
    {
        // do the button action here.
    }
} );