Don Quixote
Don Quixote

Reputation: 235

Return value from child thread

I'm writing an Android app that communicates with a website. Any time I hit the website, I'm displaying a ProcessDialog so that the user knows something's happening. Most of my website communication is one-way, so I don't usually expect any return data.

There is one point however where I need to get information back, but the results are not being stored when I exit the child thread. In a nutshell, I need to call a thread, let it process the results, and store the results in a couple of fields.

Here's what I've got so far - I have two variables, String[] Account and boolean AccountRetrievalSuccess:

public void GetAccount() {
    MyDialog = ProgressDialog.show( MyContext, "Retrieving Account" , "We're retrieving your account information. Please wait...", true);
    Thread T = new GetAccountThread();
    T.start();
}

public class GetAccountThread extends Thread {
   @Override
    public void run() {
       try {
           String resp = GetPage(BaseURL+MainPage+"?P="+PhoneID+"&K="+WebAccessKey+"&A=ACCOUNT");
           if (resp.contains("FAILURE|")){
               failhandler.sendEmptyMessage(0);
           } else {
               resp = resp.replace("SUCCESS|", "");
               Account = resp.split("\\|");
               handler.sendEmptyMessage(0);
            }
       } catch (Exception e) {
           failhandler.sendEmptyMessage(0);
       }
    };

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            AccountRetrievalSuccess = true;
            MyDialog.dismiss();
        }
    };

    private Handler failhandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            AccountRetrievalSuccess = false;
            MyDialog.dismiss();
            ShowWtf();
        }
    };
}

Any idea what I'd need to do to be able to store the Account and AccountRetrievalSuccess values so that I can access them from elsewhere in the code?

Upvotes: 0

Views: 2234

Answers (4)

botteaap
botteaap

Reputation: 5790

Looks like a perfect job for AsyncTask!

This class allows you to run a task on a background thread and return the results back to the UI thread whilst reporting progress on the task at hand.

Not expecting a result in a mobile app might be a bad idea by the way, due to nature of mobile network connections you'd never know for sure if your server actually got the thing you sent it (and the server might have failed while processing and your app would never know...)

Upvotes: 2

JAL
JAL

Reputation: 3319

Scott.. You should not have more than one handler per activity. Instead switch on what. You can send data (or objects) in messages as in:

Message msg= Message.obtainMessage(0);
Bundle b= new Bundle();
b.putString("stringData",outString);
msg.setData(b);
handler.sendMessage(msg);

You can switch on multiple messages in the handler as in.

public void  handleMessage(Message msg){        
        switch(msg.what){
            case BUTTON_ONE_UP_SELECTED:
                this.removeMessages(BUTTON_ONE_UP_SELECTED);
                buttonLarger01.setImageResource(R.drawable.btn_zoom_up_selected);
             break;                
             case BUTTON_ONE_UP_NORMAL:
                 this.removeMessages(BUTTON_ONE_UP_NORMAL);
                 buttonLarger01.setImageResource(R.drawable.btn_zoom_up_normal);
             break;
             case BUTTON_TWO_UP_SELECTED:
                 this.removeMessages(BUTTON_TWO_UP_SELECTED);
                 buttonLarger02.setImageResource(R.drawable.btn_zoom_up_selected);
             break;                
             case BUTTON_TWO_UP_NORMAL:
                  this.removeMessages(BUTTON_TWO_UP_NORMAL);
                  buttonLarger02.setImageResource(R.drawable.btn_zoom_up_normal);
             break;
             case BUTTON_ONE_DOWN_SELECTED:
                  this.removeMessages(BUTTON_ONE_DOWN_SELECTED);
                  buttonSmaller01.setImageResource(R.drawable.btn_zoom_down_selected);
             break;                
             case BUTTON_ONE_DOWN_NORMAL:
                   this.removeMessages(BUTTON_ONE_DOWN_NORMAL);
                   buttonSmaller01.setImageResource(R.drawable.btn_zoom_down_normal);
             break;
             case BUTTON_TWO_DOWN_SELECTED:
                   this.removeMessages(BUTTON_TWO_DOWN_SELECTED);
                   buttonSmaller02.setImageResource(R.drawable.btn_zoom_down_selected);
             break;                
             case BUTTON_TWO_DOWN_NORMAL:
                    this.removeMessages(BUTTON_TWO_DOWN_NORMAL);
                    buttonSmaller02.setImageResource(R.drawable.btn_zoom_down_normal);
             break;
            default:
                super.handleMessage(msg);
             break;
        }
    }
};

So in your case you could define SUCCESS as what 0 and FAILURE as what 1 etc.

Upvotes: 0

Femi
Femi

Reputation: 64700

Make those global variables in the containing Activity and then pass them to the handler:

Message m = Message.obtain();
m.obj = Account;
handler.sendMessageDelayed(m, 1);

Then in the handler you can cast m.obj back to the Account type and its nice and available.

Upvotes: 0

Rick-Rainer Ludwig
Rick-Rainer Ludwig

Reputation: 2401

Do not use threads. You should use executors for that. Implement a Callable<> interface, create an ExecutorService and run it. Have a look to the java.util.concurrent package.

Upvotes: 0

Related Questions