Thursday, February 12, 2015

Java: Doing Callbacks in Android/Java

Recently I was tasked with building an Android library for a USB device. I went through the process of documenting what this library API would look like and realized I would need to use callbacks. For example, if the Android OS prompts the user for USB permissions and the user rejects its, the app would need to know when this happens. Looking it up on Stack Overflow made me cringe as the explanations somehow made things more complicated than it should especially for dummies like myself. They went into something about onEvents and such.

Here's how I implemented with interfaces. The quick idea is that you create an interface object and declare the callback function names. The programmer wanting to implement a callback would then create an instance of this interface and override the declared functions with whatever he/she wants the callback to do and then subsequently pass this interface object to the function that requires the callback. This is unlike C where you can simply use function pointers, or high level scripting where you can just pass the name of the function you want to use as callback.

Take for example the following interface:

public interface alarmCallbackInterface {
    void alarm();
    void alarmAfterTwoMinutes();
}

The alarm function is going to be called when this said library wants to call a user-defined callback function when the alarm is going off. The alarmAfterTwoMinutes() is going to be called when the library wants to call another user-defined function when the alarm has gone off after two minutes. And here is an example of the class with a function that requires the callback function.

public class alarm{
   
   // Constructor
   public alarm(Context context) {
      ...
   }

   public functionThatUsesCB(alarmCallbackInterface callback) {
      ...

      // Call the callback!
      callback.alarm();
   }
}

Now if I was a dev using this library, I would create an instance of this interface object overriding the callback functions.

alarmCallbackInterface alarmCB = new alarmCallbackInterface(){
  @Override
  public void alarm(){
     // Do something like play mp3 tone
  }

  @Override
  public void alarmAfterTwoMinutes(){
     // Toast a notification to the user
  }
}

Then I would call the function that requires the callback.

alarm myAlarm = new alarm(this);

// Call the function that will need the call back and pass the 
// callback interface as an argument
myAlarm.functionThatUsesCB(alarmCB);

Simple. I don't know if people on Stack Overflow are just incapable of simplifying things.. or I'm just too stupid to understand their examples.

1 comment :