Callback Tutorial

1. Introduction

Target

This is a tutorial for introducing a how implement, usage, and test callback structure, for example: when you need to return different structures on one method:

// Usage a kind of callback method
service.needImagesForSomethig(id idTrack, String hashSecurity, new ServiceCallback(){
    public void successful(int code,Array<Bitmap> maps){
       // ok response
    }

    public void throwProblem(int code, ServiceException exception){
       // When you have a problem. f.e: error connection or exception
    }
} );

Dependencies

Knowledge intermediate programming

2. Getting set up

To start you need a code with interfaces classes or adapter patterns.

Download the Code

Click the following link to download all the code for this tutorial:

Download source code

What you'll learn

What you'll need

3. Write callbacks (1)

Write basic callback for two responses:

At the beginning, write a simple interface :

public interface Callback {
    void successed(Object... objects);

    void failed(Object... objects);
}

Add a response object into method instead of return type, notice your method change the return value to void.

public void trySaveData(String data, Callback callback) {
        if (!data.isEmpty())
            callback.successed("Se obtuvo la información", data);
        else
            callback.failed("Mensaje de Error");
}

Now, when you want to use it, just call:

myApi.trySaveData(txt.getText().toString(), new Callback() {
  @Override
  public void successed(Object... objects) {
     show((String) objects[0]);
     txt.append(objects[1].toString());
  }

  @Override
  public void failed(Object... objects) {
      show((String) objects[0]);
  }
});

4. Write callbacks (2)

Write enque responses:

At the beginning, write a simple interface :

public interface RestCallBack extends Callback {
    void httpOK(Object... objects);
    void errorHttp(Exception exception,Object... objects);
}

Second add a method that return the own controller/api (builder pattern)

public myController enviarData(int num, float[] decimals) {
    instance.mModel = new Model();
    instance.mModel.setNumero(num).setCifras(decimals);
    return instance;
}

Third add getRest method, to provide add method after sendData finished:

public void enqueRest(RestCallBack restCallBack) {
    if (mModel != null)
        restCallBack.httpOK(mModel.getNumero(), mModel.getCifras(), mModel);
    else
         restCallBack.errorHttp(new NullPointerException("modelo sin construir"));
}

Now, when you want to use it, just call:

myController.enviarData(0, new float[] {})
 .enqueRest(new RestCallBack() {
  @Override
  public void httpOK(Object...objects) {
   int num = (int) objects[0];
   float[] floats = (float[]) objects[1];
   Model model = (Model) objects[2];

  }

  @Override
  public void errorHttp(Exception exception, Object...objects) {
   if (exception == null)
    show(exception.getMessage());
  }

  @Override
  public void successed(Object...objects) {
   show(objects[0].toString());
  }

  @Override
  public void failed(Object...objects) {
   show(objects[0].toString());
  }
 });

5. Write callbacks (3)

Write an abstract class from three interfaces:

At the beginning, write 3 different interfaces :

// First interface
public interface SuccessCallback {
    void onSuccess(Object... objects);
}
// Second interface
public interface FailCallback {
    void onFail(Object... objects);
}
// Third interface
public interface ParseCallback {
    void onParse(ParseException exception, Object... objects);
}

Subsequently, write an abstract class which implement the 3 interfaces that we wrote them.

public static abstract class MethodCall implements 
    SuccessCallback, FailCallback, ParseCallback{}

Now, when you want to use it, just call:

myApi.getParsedObject("", new myController.MethodCall() {
    @Override
    public void onFail(Object...objects) {
        objects[0].toString();
    }

    @Override
    public void onParse(ParseException exception, Object...objects) {
        show(exception.getMessage());
    }

    @Override
    public void onSuccess(Object...objects) {
        objects[0].toString();
    }
});

6. Write callbacks (4)

Write an api with different callbacks:

At the beginning, in this part use the Callback interface from Write callbacks(1) , second :

// Attach too many callbacks
public void twoSteps(Callback...callbacks) {
    for (Callback callback: callbacks) {
        if (callback instanceof PreCallback)
            callback.successed("Pre-Success");
        else if (callback instanceof PosCallback)
            callback.failed("Pos-Fail");
    }
}

Lastly, write a statement that call the twoSteps method:

myApi.twoSteps(new PreCallback() {
    @Override
    public void successed(Object...objects) {
        show(objects[0].toString());
    }

    @Override
    public void failed(Object...objects) {
        show(objects[0].toString());
    }
}, new PosCallback() {
    @Override
    public void successed(Object...objects) {
        show(objects[0].toString());
    }

    @Override
    public void failed(Object...objects) {
        show(objects[0].toString());
    }
}, ... // You put all callbacks, that you want them
);

7. Write callbacks (5)

Write an api/controller class to use with different models:

At the beginning, write the class with templates annotations to support two different models:

Writing the interfaces:

// first interface with two template class
public interface IntTemSuper < A, B > {
    A methodSuperReturnA(B b);
}
// inheritance interface from IntTemSuper
public interface IntTemUnder < X, Y > extends IntTemSuper < X, Y > {
    Y methodPoorReturnY(X x);
}

Subsequently, write a main/api class, as a method, just do one thing and that it.

// Class with two template classes
public class TemplateController < G, H > {
    public void methodStaticCall(TemplateCallback < G, H > callback) {
        callback.methodSuperReturnA(null);
        callback.methodPoorReturnY(null);
    }

    public static abstract class TemplateCallback < TC, UC >
                   implements IntTemUnder < TC, UC > {
    }
}

Now, when you want to use it, build a new Class and call it.

new TemplateController < Model, Model2 > ()
    .methodStatickCall(new TemplateController.TemplateCallback < Model, Model2 > () {
        @Override
        public Model2 methodPoorReturnY(Model model) {
            return new Model2();
        }

        @Override
        public Model methodSuperReturnA(Model2 model2) {
            return new Model();
        }
    });

8. License

by Romell Domínguez

Copyright 2018 Romell D.Z.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,

WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

See the License for the specific language governing permissions and limitations under the License.