Возвращаемое значение из Runnable

У меня есть дни, пытаясь решить эту проблему, но я не могу, и решение этого состоит в том, чтобы перейти к Stackru:D. Бывает, что я работаю с libgdx (библиотекой для создания игр) и запрашиваю код в Android с помощью класса Handler, запускающего Runnable, и я не совсем знаю, как он работает.

По сути, я хочу получить значение из Runnable. Использование класса Handler с обратными вызовами или чем-то подобным

Я должен сказать, что я действительно не понимаю многопоточное программирование, и я видел несколько методов в классе Handler, но я не могу понять, как это работает (обмен сообщениями, обратные вызовы и т. Д.)

public class ActionResolverAndroid implements ActionResolver {
    Handler handler;
    Context context;

public ActionResolverAndroid(Context context) {
    handler = new Handler();
    this.context = context;
}

public boolean checkAndroidData(){
    final boolean[] result = {false};
    handler.post(new Runnable() {
            @Override
            public void run() {
                // Android code here
                // I need know the value of this variable
                result[0] = true;
            }
    });
    return result[0];
}

Большое спасибо за чтение. ура

pd) я не могу использовать Runnable .join() или Callable<>

2 ответа

Решение

Когда вы публикуете Runnable в обработчике, этот код будет запущен в MainThread (тот, который вы можете коснуться ваших представлений).

делать:

public boolean checkAndroidData(){
    final boolean[] result = {false};
    handler.post(new Runnable() {
            @Override
            public void run() {
                // Android code here
                // I need know the value of this variable
                result[0] = true;
            }
    });
    return result[0];
}

Будет иметь результат [0] всегда ложным, потому что Runnable еще не будет запущен.

Способ, которым вы можете уведомить себя о заключении, будет создание прослушивателя интерфейса, о котором вы сможете уведомить, когда закончится Runnable.

Рассмотрим следующую реализацию интерфейса:

public interface Listener<T> {
    void on(T arg);
}

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

public void checkAndroidData(Listener<Boolean> onCompleteListener){
    handler.post(new Runnable() {
            @Override
            public void run() {
                onCompleteListener.on(true);
            }
    });
}

И чтобы позвонить, вы должны передать экземпляр и дождаться ответа, например:

void onCreate(Bundle s){
    super.onCreate(s);
    checkAndroidData(new Listener<Boolean>(){
        public void on(Boolean result){
                Toast.makeText(result, Toast.LENGHT_LONG).show();
        }
    });
}

Что ж, это пример, и в этом случае оба кода будут выполняться в MainThread, этот пример охватывает не многопоточность, а способ прослушивания события, которое вы начали.

Но решение применимо к многопоточности, если сделано в этом контексте.

Вы можете использовать обратный вызов:

public interface RunnableListener
{
    void onResult(boolean[] result);
}

// a field in your class 
private RunnableListener runnableListener;

private void someMethod()
{
    new Handler().post(new Runnable()
    {
        @Override public void run()
        {
            runnableListener.onResult(new boolean[]{true});
        }
    });
}
Другие вопросы по тегам