josemwarrior
josemwarrior

Reputation: 378

Return value from Runnable

I have days trying to solve this but I can't, and the solution to this is to go to StackOverflow :D. Happens that I'm working with libgdx (library to make games) and to query code in Android is through the Handler class, running a Runnable and I don't really know how it works.

Basically what I want is to retrieve a value from Runnable. Using the Handler class with callbacks or something like that

I have to say that I don't really understand multithreading programming, and I saw several methods in Handler class, but I can't understand how it works (messaging, callbacks, etc.)

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

Thanks a lot for reading. cheer

pd) I can't using Runnable .join() or Callable<>

Upvotes: 5

Views: 17233

Answers (2)

a person
a person

Reputation: 986

You can use a callback:

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

Upvotes: 3

Marcos Vasconcelos
Marcos Vasconcelos

Reputation: 18276

When you post a Runnable to the Handler, that code will RUN in the MainThread (the one that you can touch your views).

doing:

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

Will make the result[0] being always false cause the Runnable would not runned yet.

The way you can notify yourself about the conclusion would be creating a Interface listener that you can notify when the Runnable ends.

Consider the following interface implementation:

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

Working with a Listener would be waiting the response in the listener instead of the return value of a method, so the method above would be like:

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

And to call, you would pass a instance and wait for the response, like:

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

Well, this is a example, and in this case both code will run in the MainThread, this example doesnt cover multithreading, but about how to listen to the event that you started.

But the solution applies to multithreading if done in that context.

Upvotes: 7

Related Questions