-1

I have a problem, I am trying to access a private variable of an outer class from a doInBackground method of an AsyncTask which is the inner class. Here there is the full code.

public class MessageHandler {
private Contact receiver;
private String senderFacebookId;
private String message;
private final String TAG = "MessageHandler";
private Context context;
boolean sentResult;

public MessageHandler(Contact receiver, String senderFacebookId, String message, Context context) {
    this.receiver = receiver;
    this.senderFacebookId = senderFacebookId;
    this.message = message;
    this.context=context;
    this.sentResult = false;
}

public void send(){
    Log.i(TAG, "Sending message to " + receiver.getName() + " receiver id: " + receiver.getFacebook_id() + " sender id: " + senderFacebookId + " message: " + message);

    new SenderAsync().execute(senderFacebookId,message, receiver.getFacebook_id());
    if(this.sentResult==true){
        Toast toast = Toast.makeText(this.context, "Message Sent", Toast.LENGTH_LONG);
        toast.show();

    }else{
        Toast toast = Toast.makeText(this.context, "ERROR: Message not Sent", Toast.LENGTH_LONG);
        toast.show();
    }
}



private class SenderAsync extends AsyncTask<String,String,String> {

    @Override
    protected void onPreExecute(){
        super.onPreExecute();
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
    }

    @Override
    protected String doInBackground(String... params) {
        HttpClient client = new DefaultHttpClient();

        try {
            List<NameValuePair> parameter = new ArrayList<>(1);
            parameter.add(new BasicNameValuePair("regId", "empty"));
            parameter.add(new BasicNameValuePair("sender_id", params[0]));
            parameter.add(new BasicNameValuePair("receiver_facebook_id", params[2]));

            parameter.add(new BasicNameValuePair("message", params[1]));

            String paramString = URLEncodedUtils.format(parameter, "utf-8");
            HttpGet get = new HttpGet(ProfileFragment.SERVER_URL_SEND_MESSAGE+"?"+paramString);

            Log.i(TAG, paramString);
            HttpResponse resp = client.execute(get);
            System.out.println("SREVER RESPONSE " + resp.getStatusLine().getStatusCode());

            //THIS IS THE VARIABLE THAT I WANT TO ACCESS
            if(resp.getStatusLine().getStatusCode()==200){
                MessageHandler.this.sentResult = true;
            }



        } catch (IOException e) {

            Log.i(TAG,"Error :" + e.getMessage());
        }
        return null;
    }
}

}

The variable that I am trying to access is the boolean variable sentResult. I also print out the response of the server which is always 200. Even if I remove the if condition and I set it to be true in any case, it looks like that that line of code is never executed and the variable not accessed, so it is always false.

arodriguezdonaire
  • 5,396
  • 1
  • 26
  • 50
FF91
  • 29
  • 1
  • 11
  • May be you have an exception before that line? – Vigen Aug 08 '15 at 20:56
  • inside send function after execute you check value of the sentResult. I think it is always false, because AsyncTask is a separate thread. check that value in onPostExecute – Vigen Aug 08 '15 at 21:00

4 Answers4

2

The entire point of an async task is that it is asynchronous. If you execute a task, you will not get the results back on your next line of code. In order to evaluate the result, you should be using the onPostExecute callback method.

@Override
protected void onPostExecute(String s) {
    if(sentResult==true){
        Toast toast = Toast.makeText(this.context, "Message Sent", Toast.LENGTH_LONG);
        toast.show();
    }else{
        Toast toast = Toast.makeText(this.context, "ERROR: Message not Sent", Toast.LENGTH_LONG);
        toast.show();
    }
}

Also, if you were to change your method signatures, you wouldn't even need an external variable.

private class SenderAsync extends AsyncTask<String,String,Boolean> {

@Override
protected void onPostExecute(Boolean sent) {
    if(sent == true){
        Toast toast = Toast.makeText(this.context, "Message Sent", Toast.LENGTH_LONG);
        toast.show();
    }else{
        Toast toast = Toast.makeText(this.context, "ERROR: Message not Sent", Toast.LENGTH_LONG);
        toast.show();
    }
}

@Override
protected Boolean doInBackground(String... params) {
    try {
        ...
        if (resp.getStatusLine().getStatusCode() == 200) {
            return true;
        }
    }
    catch (IOException e) {

    }

    return false;
}
tachyonflux
  • 20,103
  • 7
  • 48
  • 67
  • Hello, I am getting a similar prob which I think you might be able to solve. I would be glad if you could look into it: https://stackoverflow.com/questions/50534854/android-accessing-a-variable-of-an-inner-asynctask-class-but-getting-it-as-null# – Tia May 25 '18 at 20:18
0

Create Constructor for SenderAsync;

public SenderAsync(Context context, String senderId, String msg, Contact receiver)

Call it this way;

new SenderAsync(senderFacebookId,message, receiver.getFacebook_id()).execute();

And you need to get your result in onPostExecute. void onPostExecute(String returnedValue) { // Run the if statement you want here }

Want2bExpert
  • 527
  • 4
  • 11
0

You are trying to verify sentResult right after you tell the AsyncTask to do its work. The AsyncTask does what it has to do on a separate thread, in parallel. So until it finishes, the sentResult is unchanged.

What I suggest is to put your Toast logic in onPostExecute.

Andrei Tudor Diaconu
  • 2,157
  • 21
  • 26
0

You are using AsyncTask incorrectly. AsyncTask should return results in onPostExecute() and your UI should have a seperate method onPostExecute() calls (hence the asynchronous name). For what you are trying to accomplish, you should be doing it like this:

public void send() {
    new SenderAsync().execute(senderFacebookId,message, receiver.getFacebook_id());
}

public void processResult(boolean result) {
  String resultMsg = result ? "Message Sent" : "ERROR: Message not Sent";
  Toast.makeText(this.context, resultMsg, Toast.LENGTH_LONG).show();
}

private class SenderAsync extends AsyncTask<String, String, Boolean> {
  ...
  @Override
    protected String doInBackground(String... params) {
      ...
      try {
        ...
        return (resp.getStatusLine().getStatusCode() == 200)
      }
      ...
      return false;
    }

    @Override
    protected void onPostExecute(Boolean result) {
        processResult(result);
    }
}
jt-gilkeson
  • 2,661
  • 1
  • 30
  • 40