FF91 FF91 - 2 months ago 21
Android Question

Access private variable from inner class (AsyncTask)

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.

Answer

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