Reputation: 9336
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
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 Handler
s, but once you get to know them, they are easy and very powerful.
Upvotes: 3
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