Search code examples
javaandroidoverridingrunnable

How to properly override Runnable.run(), so it can take parameters?


I am currently working on an android project and came across the situation, that I have to pass a function as parameter, so I browsed StackOverflow and tried out solution, to encapsulate the function with a Runnable.

The problem I'm now facing is, that the function I want to pass, expects parameters and Runnable.run() doesn't take any. So I'm currently trying to extend Runnable and override run() to let it accept parameters, which I can then pass to the actual function.

Now I'm kinda unsure, as run() is used in Thread on how I can override it, without knocking out Thread. I don't use any other Thread methods so far. Any suggested approach?

EDIT

The target is, to call these custom Runnables inside a listener method like so:

public void startRequest(RequestOperation operation, final Runnable onSuccess, final Runnable onError, final Runnable onFinished) {

    JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, instance_context.getResources().getString(R.string.base_url), null, new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {
            onSuccess.run();
            onFinished.run();
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            onError.run();
            onFinished.run();
        }
    });
    queue.add(request);
}

In best case, onSuccess is able get the response object passed, as onError gets the error.


Solution

  • Why force Runnable into being something it's not designed to be? Simply have your own interface that has the signature you require. E.g.

    public interface Callback<T> {
        void run(T parameter);
    }
    
    public void startRequest(RequestOperation operation, final Callback<JSONObject> onSuccess, final Callback<VolleyError> onError, final Runnable onFinished) {
    
        JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, instance_context.getResources().getString(R.string.base_url), null, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                onSuccess.run(response);
                onFinished.run();
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                onError.run(error);
                onFinished.run();
            }
        });
        queue.add(request);
    }
    

    Or even better (if you ask me):

    public interface Callback {
        void onSucces(JSONObject response);
        void onError(VolleyError error);
        void onFinished();
    }
    
    public void startRequest(RequestOperation operation, final Callback callback) {
    
        JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, instance_context.getResources().getString(R.string.base_url), null, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                callback.onSuccess(response);
                callback.onFinished();
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                callback.onError(error);
                callback.onFinished();
            }
        });
        queue.add(request);
    }
    

    You can also make Callback generic again, if you need to:

    public interface Callback<R, E> {
        void onSucces(R response);
        void onError(E error);
        void onFinished();
    }
    
    public void startRequest(RequestOperation operation, final Callback<JSONObject, VolleyError> callback) {...}
    

    To use:

    public class SimpleCallback implements Callback {
        public void onSucces(JSONObject response) {
            doSomethingWithResponse(response);
        }
    
        public void onError(VolleyError error) {
            doSomethingWithError(error);
        }
    
        void onFinished() {
            logFinishTime();
        }
    }
    
    startRequest(operation, new SimpleCallback());