A Simple Callback in Java for Android

It all started when I received a NetworkOnMainThreadException while testing an Android prototype that makes an HTTP request to my backend. It means simply that you can't make the request in the main thread. So the quick and proper solution is to extend AsyncTask for it:

public class FooJob extends AsyncTask<String, Void, Response> {
    @Override
    protected Response doInBackground(String[] params) {
        Log.i(TAG, "job started");
        Response response = doSomething(params);
        return response;
    }
    
    @Override
    protected void onPostExecute(Response response) {
        Log.i(TAG, "job ended");
    }
}

Then you simply call this from your activity:

public void start() {
    new FooJob().execute(params);
}

This all works good, yet the caller needs to be notified on the response to take further action - in my case launch the next screen.

I've tried a different approach to this on iOS part to publish notifications - so that any listener can be notified of the request completion, but I wanted to keep it simple for Android. In the end, I have only started programming Android last weekend!

So, for the callback, you simply create a new interface:

public interface ResponseListener {
    void onCompleted(Response response);
}

Then use this in the FooJob class so the final version becomes:

public class FooJob extends AsyncTask<String, Void, Response> {

    private final ResponseListener listener;
    
    public FooJob(ResponseListener listener) {
        this.listener = listener;
    }
    
    @Override
    protected Response doInBackground(String[] params) {
        Log.i(TAG, "job started");
        Response response = doSomething(params);
        return response;
    }
    
    @Override
    protected void onPostExecute(Response response) {
        Log.i(TAG, "job ended, calling back");
        listener.onCompleted(response);
    }
}

Last step, when constructing the FooJob class, provide the implementation for ResponseListener:

public void start() {
    new FooJob(new ResponseListener(){
        @Override
        public void onCompleted(Response response) {
            Log.i(TAG, "response received in callback");
            launchNextScreen();
        }
    })
    .execute(params);
}