0

I created a REST API which appears to work fine (I tested the GET request of interest using Postman).

I am working to make an identical request from an Android application using an AsyncTask. The hope is to assign a string value generated by the AsyncTask to a string variable in the Android activity.

I have used a Toast to view the string output of the doInBackground method, which is passed to the onPostExecute method of the AsyncTask, to make sure that the call to the API is working and it works fine.

The problem comes when I assign the string output of the AsyncTask to the string variable defined in the Activity class. After executing the AsyncTask I am using a Toast to view the value of the string variable and it is reflecting the assignment performed in the onPostExecute method.

I will now share the code that I am using in the hope that you can help me to find where I might be going wrong. After the button is clicked, I intend for the validate AsyncTask to execute and assign a value to emailValid.

In view of the code below, my question in the most direct way I can put it: "Why is Toast 2 displaying while Toast 1 is not?"

Thank you in advance for your assistance.

public class JoinActivity extends AppCompatActivity implements View.OnClickListener
{
    EditText email_et;
    Button join_b;

    String emailValid;

    @Override
    protected void onCreate(Bundle savedInstance)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_join);
        emailValid = "No";
        join_b = (Button) findViewById(R.id.aj_join_b);
        join_b.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) 
    {
        email_et = (EditText) findViewById(R.id.et_aj_email_address);
        new JoinActivity.validate().execute(email_et.getText().toString());
        // Toast 1 here:
        Toast.makeText(getApplicationContext(), emailValid, 
            Toast.LENGTH_LONG).show();
    }

    private class validate extends AsyncTask<String, Void, String> 
    {
        @Override
        protected String doInBackground(String... params) 
        {
            // ... GET request produces string with either yes or no i.e. outcome
            return outcome;
        }
        @Override
        protected void onPostExecute (String s) 
        {
            // Toast 2 here:
            Toast.makeText(getApplicationContext(), s, Toast.LENGTH_LONG).show();
            emailValid = s;
            super.onPostExecute(s);
        }
    }
}

As requested, the detail in the doInBackground method is pasted below. The method actually return some XML. My original question which said "a string variable which is either a "yes" or "no"" was my attempt to simplify the setup. As I mentioned before, displaying the string in a Toast from within the onPostExecute works fine showing the participantXML sent from the doInBackground:

@Override
protected String doInBackground(String... params) {
    InputStream inputStream;
    String emailAddress = params[0];
    String outcome = null;
    HttpURLConnection httpURLConnection = null;
    BufferedReader bufferedReader = null;
    try
    {
        URL url = new URL("http://10.0.2.2:8080/project_name/webresources/entity.participant/email");
        httpURLConnection = (HttpURLConnection) url.openConnection();
        httpURLConnection.setRequestMethod("GET");
        httpURLConnection.setRequestProperty("Accept", "application/xml");
        httpURLConnection.addRequestProperty("Email-address", emailAddress);
        httpURLConnection.connect();
        inputStream = httpURLConnection.getInputStream();
        StringBuffer stringBuffer = new StringBuffer();
        if (inputStream == null) {
            return null;
        }
        bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        String line;
        while ((line = bufferedReader.readLine()) != null) {
            stringBuffer.append(line + "\n");
        }
        if (stringBuffer.length() == 0) {
            return participantXML;
        }
        participantXML = stringBuffer.toString();
    } catch (ProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (httpURLConnection != null) {
            httpURLConnection.disconnect();
        }
        if (bufferedReader != null) {
            try {
                bufferedReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    validEmailAddress = participantXML;
    return participantXML;
}
Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
SomeGuy
  • 1
  • 3
  • There seems to some problem in the code you have provided here. The `validate` class in the above code is not the same one that you have called by writing `new JohnActivity.validate...`. If indeed the `validate` class is the one that's getting called, put it in `JohnActivity` – Pulak Jan 13 '18 at 12:08
  • Did you try putting a debugger in onPostExecute method and see if it is getting called? Are you getting a valid response in doInBackgroud()? – LeoNeo Jan 13 '18 at 12:14
  • @Pulak: The perils of copy and paste. I have edited the code to reflect that there is only one activity not two which is JoinActivity. – SomeGuy Jan 13 '18 at 12:15
  • @LeoNeo: No I have not tried your suggestion. Thus far, I have been using the Toast message as a means to see where things appear to be going wrong. I confess I have never used the debugger and will read up on how to use it. Is it your sense that even though the Toast message placed inside the onPostExecute displays the string s the method may not be getting called still? That confuses me, to be honest. – SomeGuy Jan 13 '18 at 12:19
  • No my suspicion is that you might be hitting an exception in doInBackground which results in onPostExecute never being called. Can you post the code in doInBackground() ? and what exactly is the response that you see in Postman for the call? – LeoNeo Jan 13 '18 at 12:24
  • Use the following link to learn how to debug the app :https://developer.android.com/studio/debug/index.html Look for *Start debugging* header.. points 1-4 – LeoNeo Jan 13 '18 at 12:25
  • @LeoNeo: The response that is received from Postman is XML with details of a participant object. – SomeGuy Jan 13 '18 at 12:49

1 Answers1

0

The answer by user3691697 to this question: How to get the result of OnPostExecute() to main activity because AsyncTask is a separate class? did the trick. I created task object (myTask) when executing the task and thereafter used it to assign the result to the variable like this:

AsyncTask myTask = new JoinActivity.validate.execute(email_et.getText().toString());

emailValid = myTask.get().toString();

The Toast message confirms that the assignment worked! Thank you for the help Pulak and LeoNeo.

SomeGuy
  • 1
  • 3