How to Perform a Java Callback Between Classes

How do I perform a JAVA callback between classes?

Define an interface, and implement it in the class that will receive the callback.

Have attention to the multi-threading in your case.

Code example from http://cleancodedevelopment-qualityseal.blogspot.com.br/2012/10/understanding-callbacks-with-java.html

interface CallBack {                   

//declare an interface with the callback methods,
//so you can use on more than one class and just
//refer to the interface

void methodToCallBack();
}

class CallBackImpl implements CallBack {

//class that implements the method to callback defined
//in the interface

public void methodToCallBack() {
System.out.println("I've been called back");
}
}

class Caller {

public void register(CallBack callback) {
callback.methodToCallBack();
}

public static void main(String[] args) {
Caller caller = new Caller();
CallBack callBack = new CallBackImpl();

//because of the interface, the type is Callback even
//thought the new instance is the CallBackImpl class.
//This alows to pass different types of classes that have
//the implementation of CallBack interface

caller.register(callBack);
}
}

In your case, apart from multi-threading you could do like this:

interface ServerInterface {
void newSeverConnection(Socket socket);
}

public class Server implements ServerInterface {

public Server(int _address) {
System.out.println("Starting Server...");
serverConnectionHandler = new ServerConnections(_address, this);
workers.execute(serverConnectionHandler);
System.out.println("Do something else...");
}

void newServerConnection(Socket socket) {
System.out.println("A function of my child class was called.");
}

}

public class ServerConnections implements Runnable {

private ServerInterface serverInterface;

public ServerConnections(int _serverPort, ServerInterface _serverInterface) {
serverPort = _serverPort;
serverInterface = _serverInterface;
}

@Override
public void run() {
System.out.println("Starting Server Thread...");

if (serverInterface == null) {
System.out.println("Server Thread error: callback null");
}

try {
mainSocket = new ServerSocket(serverPort);

while (true) {
serverInterface.newServerConnection(mainSocket.accept());
}
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

Multi-threading

Remember this does not handle multi-threading, this is another topic and can have various solutions depending on the project.

The observer-pattern

The observer-pattern does nearly this, the major difference is the use of an ArrayList for adding more than one listener. Where this is not needed, you get better performance with one reference.

Callback functions in Java

If you mean somthing like .NET anonymous delegate, I think Java's anonymous class can be used as well.

public class Main {

public interface Visitor{
int doJob(int a, int b);
}

public static void main(String[] args) {
Visitor adder = new Visitor(){
public int doJob(int a, int b) {
return a + b;
}
};

Visitor multiplier = new Visitor(){
public int doJob(int a, int b) {
return a*b;
}
};

System.out.println(adder.doJob(10, 20));
System.out.println(multiplier.doJob(10, 20));

}
}

Java simple callback

You can define an interface for the callback.

interface Callback{
void call();
}

Then, let class A implement it.

class A implements Callback{
private B b;

public A(){
b = new B();
b.registerCallback(this);
}

// Implementation of the callback interface
public void call(){

}
}

Then, let class B to handle the callback.

public class B
{
private Callback callbackoNotify;

public class registerCallback(Callback callback)
{
callbackoNotify = callback;
}

public void notify()
{
callbackNotify.call();
}
}

But in the above scenario, callbackNotify can be null. Therefore, it is better if you can pass that callback in the constructor to B.

Hope you got the idea.

Java callback (in another class) to populate private member

Pass dl to the ToolResultCallback constructor, and store it in a field.

Thanks @tgdavies

How can I call a class variable from a callback function?

You are close, since you are within an inner class you have to prefix this with a little extra information:

MyClass.this.myObject = myObject;

Otherwise this refers to the anonymous Callback class you are defining.

Callback Method Android

Chris, Imagine that you have a function:

fun test() {
...
}

Then you decided to add some magic to it. For instance, add 'block' that could be done after function test finished its job. So, here we need to put some extra into code:

interface CallbackInterface {
fun doJob()
}

and your function become:

fun test(block: CallbackInterface) {
...
block.doJob()
}

so then you can call your test function like this (or pass CallbackInterface into test function):

test(object: CallbackInterface {
override fun doJob() {
...
}
})

In general, the point is to pass the interface as a parameter in function and call it whenever you want and do on another end do whatever you want with the results.

or in Kotlin you can do like this:

fun test(block: ()-> Unit) {
...
block.invoke() // or just block()
}

and use it:

test {
...
}

How to pass different callbacks to same function in android

I would like to recommend to have a separate interface class without keeping it inside of a Class or Activity.

So declare an interface like this. Create a separate file.

public interface VolleyCallback {
void onSuccess(String result);
}

Then create a public instance of the VolleyCallback interface in your VolleyAPIService class like the following. Remove the parameter from the volleyPost method for cleaner implementation.

public class VolleyAPIService {

public VolleyCallback callback;

public void volleyPost(String URL, Map<String, String> param, Context context) {
RequestQueue requestQueue = Volley.newRequestQueue(context);
final Map<String, String> params = param;

StringRequest stringRequest = new StringRequest(Request.Method.POST, URL,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
callback.onSuccess(response);
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
}) {
@Override
protected Map<String, String> getParams() {;
return params;
}
};
requestQueue.add(stringRequest);
}
}

Now from your MainActivity, implement the interface that you have created and override the callback function like the following.

public class MainActivity extends AppCompatActivity implements VolleyCallback {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

companyLogin("abc", "123");
}
public interface VolleyCallback {
void onSuccess(String result);
}

public void companyLogin(String companyname, String password) {
RequestQueue requestQueue = Volley.newRequestQueue(this);
String URL = "http://...";
final Map<String, String> params = new HashMap<String, String>();
params.put("name", companyname);
params.put("pwd", password);

Intent volley_service = new Intent(MainActivity.this, VolleyAPIService.class);
MainActivity.this.startService(volley_service);

VolleyAPIService volleyAPIService = new VolleyAPIService();

// Assign the callback here to listen the response from the API service.
volleyAPIService.callback = this;
volleyAPIService.volleyPost(URL, params, MainActivity.this);
}

@Override
public void onSuccess(String result) {
// Handle the success or failure here
if (!result.isEmpty()) {
Intent userLoginActivity = new Intent(MainActivity.this, UserLogin.class);
startActivity(userLoginActivity);
} else {
AlertDialog.Builder login_failed = new AlertDialog.Builder(MainActivity.this);
login_failed.setMessage("Login Failed, invalid credentials")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {

}
});

AlertDialog alert = login_failed.create();
alert.show();
}
}
}

Do the same for your UserLogin class.

In case of having multiple API calls in a single Activity or Fragment, you might want to keep a flag in the VolleyAPIService class and passing that to the callback function you can detect which API response you are getting in your onSuccess callback.

Hope that is clear. Please feel free to ask any questions.



Related Topics



Leave a reply



Submit