Kevin Cruijssen
Kevin Cruijssen

Reputation: 9336

Set boolean from outside Thread, inside the Thread-run

I've got a boolean outside the Thread. Then I use a method that requires a Thread around it that returns a boolean. How can I set the boolean outside the thread with the returned boolean?

Code:

// Handle Automatic E-Mail Sending in a new Thread
new Thread(new Runnable() {
    @Override
    public void run() {
        // Since we want to display a Toast from within a different Thread,
        // we need to use the runOnUiThread to display it
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(ChecklistActivity.cActivity, D.T_SENDING_EMAIL, Toast.LENGTH_LONG).show();
            }
        });
        /*TODO: emailSuccessfullySent = */EMailSender.SendEmail();
    }
}).start();

I've read somewhere I could do it with a final array like so:

final boolean[] array = new boolean[1];
// Handle Automatic E-Mail Sending in a new Thread
new Thread(new Runnable() {
    @Override
    public void run() {
        // Since we want to display a Toast from within a different Thread,
        // we need to use the runOnUiThread to display it
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(ChecklistActivity.cActivity, D.T_SENDING_EMAIL, Toast.LENGTH_LONG).show();
            }
        });
        array[0] = EMailSender.SendEmail();
    }
}).start();
emailSuccessfullySent = array[0];

But I find this rather odd. Is this the generally accepted way to set a value from within a Thread, or is there a better way to do this?

Upvotes: 2

Views: 1014

Answers (2)

JorganPubshire
JorganPubshire

Reputation: 807

It requires a little more overhead, but the best way to approach this problem in Android is to use a Handler. A Handler is a structure which you can use to receive messages from multiple threads and execute code on the thread the Handler is defined in. By overriding the handleMessage(Message msg) method and defining a few constants, you can send messages from any thread and have them be handled in your UI thread.

Code:

public boolean variable = false;
private class MyHandler extends Handler {
    public static final int MESSAGE_TOAST = 1;
    public static final int THREAD_RETURN = 2;

    public void handleMessage(Message msg){
        if(msg.what == MESSAGE_TOAST){
            Toast.makeText(msg.getData().getString("toast"), Toast.LENGTH_LONG).show();
        } else if(msg.what == THREAD_RETURN){
            variable = msg.getData().getBoolean("returnValue");
        }
    }
}
public MyHandler handler = new MyHandler();

This would make your thread look like this:

// Handle Automatic E-Mail Sending in a new Thread
new Thread(new Runnable() {
    @Override
    public void run() {
        Bundle bundle = new Bundle();
        bundle.setString("toast","I want to display this message");
        Message msg = handler.obtainMessage(MyHandler.MESSAGE_TOAST);
        msg.setData(bundle);
        msg.sendToTarget();
        bundle.setBoolean("returnValue", EMailSender.SendEmail());
        msg = handler.obtainMessage(MyHandler.THREAD_RETURN);
        msg.setData(bundle);
        msg.sendToTarget();
   }
}).start();

It's a little confusing when you start using Handlers, but once you get to know them, they are easy and very powerful.

Upvotes: 3

Yash Sampat
Yash Sampat

Reputation: 30611

There is nothing special about setting the value of a non-synchronized variable inside a Thread. Since your boolean is declared "outside" the scope of your Thread, what you have done is a perfectly acceptable way of doing it. The point here is the scope of the boolean. You don't need to use an array, though. And the final qualifier is simply because variables declared outside the scope of an inner class cannot be accessed if they are not final.

Upvotes: 0

Related Questions