Как правильно переопределить Runnable.run(), чтобы он мог принимать параметры?

#java #android #overriding #runnable

#java #Android #переопределение #runnable

Вопрос:

В настоящее время я работаю над проектом Android и столкнулся с ситуацией, когда я должен передать функцию в качестве параметра, поэтому я просмотрел StackOverflow и опробовал решение, чтобы инкапсулировать функцию с Runnable .

Проблема, с которой я сейчас сталкиваюсь, заключается в том, что функция, которую я хочу передать, ожидает параметры и Runnable.run() не принимает никаких. Итак, в настоящее время я пытаюсь расширить Runnable и переопределить run() , чтобы позволить ему принимать параметры, которые я затем могу передать фактической функции.

Теперь я немного не уверен, как run() используется в Thread , как я могу переопределить его, не отключая Thread . Я пока не использую никаких других Thread методов. Какой-либо предлагаемый подход?

Редактировать

Цель состоит в том, чтобы вызвать эти пользовательские Runnables внутри метода прослушивателя следующим образом:

 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);
}
  

В лучшем случае onSuccess может передать response объект, так как onError получает error .

Комментарии:

1. нет. переопределение метода (или его реализация) означает, что вы будете использовать точно такую же сигнатуру метода, которая включает параметры.

2. Вы могли бы использовать Java Consumer, который принимает один аргумент и похож на Runnable функциональный интерфейс.

3. @Stultuske есть ли случайно способ обернуть фактический метод внутри run() then?

4. Один из способов решить эту проблему — реализовать Runnable интерфейс и добавить response в качестве поля класса.

5. @AndrianekenaMoise Я думал именно так: D, в настоящее время пытаюсь это

Ответ №1:

Зачем заставлять Runnable быть тем, для чего он не предназначен? Просто создайте свой собственный интерфейс с требуемой сигнатурой. Например.

 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);
}
  

Или даже лучше (если вы спросите меня):

 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);
}
  

Вы также можете снова создать Callback generic, если вам нужно:

 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) {...}
  

Для использования:

 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());
  

Комментарии:

1. Это в значительной степени то, что я имел в виду. Итак, чтобы определить явное содержимое onSuccess / onError / onFinished внутри компонентов, вызывающих startRequest метод, они должны затем реализовать интерфейс?

2. @procra обновил ответ. Вы, конечно, должны предоставить реализацию Callback , точно так же, как вы должны были бы предоставить реализацию Runnable .