Возвращаемое значение из 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});
}
});
}