HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Identify Java Callback

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
callbackidentifyjava

Problem

I have this common design in my application:

public class MyListener1{
  MyTask1 task1;
  MyTask2 task2;

  public class MyListener1{

    public MyListener1(){
      task1 = new MyTask1(this);
      task2 = new MyTask2(this);
      task1.execute();
      task2.execute();
    }

    public void onResult1(String result){
      //extract result
    }

    public void onResult2(String result){
      //extract result
    }
}

public class MyTask1 extends AsyncTask{

  MyListener1 myListener1;

  public MyTask1(MyListener1 myListener1){
    this.myListener1 = myListener1;
  }

  @Override
  public void onResult(String result){
    myListener1.onResult1(result);
  }

}

public class MyTask2 extends AsyncTask{

  MyListener1 myListener1;

  public MyTask2(MyListener1 myListener1){
    this.myListener1 = myListener1;
  }

  @Override
  public void onResult(String result){
    myListener1.onResult2(result);
  }

}


The AsyncTask is a library class that execute the code in a method doInBackground() in another thread when calling execute(), and call onResult(String result) when task finished.

Of course, I summarize the code, MyTask1 and MyTask2 have a little bit more code, but I soon realized that they could be factorize on a common task:

public class MyListener1{
  MyTask task1;
  MyTask task2;

  public class MyListener1{

    public MyListener1(){
      task1 = new MyTask(0,this);
      task2 = new MyTask(1,this);
      task1.execute();
      task2.execute();
    }

    public void onResult(int taskId, String result){
       switch(taskId){
         case(0) : //extract result from task 0
         case(1) : //extract result from task 1
    }
}

public class MyTask extends AsyncTask{

  int id;
  MyListener1 myListener1;

  public MyTask(int id, MyListener1 myListener1){
    this.id = id;
    this.myListener1 = myListener1;
  }

  @Override
  public void onResult(String result){
    myListener1.onResult(id, result);
  }

}


I heard some people telli

Solution

A listener and callback mechanism is a common pattern in many places in Java.

The logical place to look for examples is in the Swing API. Will get back to that in a second, but, there are two items that are useful first:

-
Instead of using an int value to track the source of the event/Task, you should use the task itself.

public void onResult(String result){
     myListener1.onResult(this, result);
   }


-
The Listener itself should implement an interface, something like: TaskResultListener:

public interface TaskResultListener {
     public onResult(Task task, String result);
 }


and the constructor for the Task should take an instance of a TaskResultListener instead of a MyListener1

For examples of how this is used, consider the ActionListener interface and usage in Swing:

  • ActionListener



  • Example implementation of ActionListener: TextAction



  • Example component that calls-back to an ActionListener: JButton / AbstractButton



In the Swing API, it is common to have support for multiple listeners. You have just one. That is OK.

Code Snippets

public void onResult(String result){
     myListener1.onResult(this, result);
   }
public interface TaskResultListener {
     public onResult(Task task, String result);
 }

Context

StackExchange Code Review Q#47709, answer score: 6

Revisions (0)

No revisions yet.